blob: 9326bff0fbff27e12d7a55ba10932798b039494e [file] [log] [blame]
Christopher Ferris3958f802017-02-01 15:44:40 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <elf.h>
18
19#include <memory>
20
21#include <gtest/gtest.h>
22
Christopher Ferrisd226a512017-07-14 10:37:19 -070023#include <unwindstack/ElfInterface.h>
24
25#include "DwarfEncoding.h"
Christopher Ferris3958f802017-02-01 15:44:40 -080026#include "ElfInterfaceArm.h"
27
Christopher Ferrise69f4702017-10-19 16:08:58 -070028#include "ElfFake.h"
Christopher Ferris3958f802017-02-01 15:44:40 -080029#include "MemoryFake.h"
30
31#if !defined(PT_ARM_EXIDX)
32#define PT_ARM_EXIDX 0x70000001
33#endif
34
35#if !defined(EM_AARCH64)
36#define EM_AARCH64 183
37#endif
38
Christopher Ferrisd226a512017-07-14 10:37:19 -070039namespace unwindstack {
40
Christopher Ferris3958f802017-02-01 15:44:40 -080041class ElfInterfaceTest : public ::testing::Test {
42 protected:
43 void SetUp() override {
44 memory_.Clear();
45 }
46
47 void SetStringMemory(uint64_t offset, const char* string) {
48 memory_.SetMemory(offset, string, strlen(string) + 1);
49 }
50
51 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
52 void SinglePtLoad();
53
54 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
55 void MultipleExecutablePtLoads();
56
57 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
58 void MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr();
59
60 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
61 void NonExecutablePtLoads();
62
63 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
64 void ManyPhdrs();
65
Christopher Ferrisbeae42b2018-02-15 17:36:33 -080066 enum SonameTestEnum : uint8_t {
67 SONAME_NORMAL,
68 SONAME_DTNULL_AFTER,
69 SONAME_DTSIZE_SMALL,
70 SONAME_MISSING_MAP,
71 };
72
73 template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
74 void SonameInit(SonameTestEnum test_type = SONAME_NORMAL);
75
76 template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -080077 void Soname();
78
Christopher Ferrisbeae42b2018-02-15 17:36:33 -080079 template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -080080 void SonameAfterDtNull();
81
Christopher Ferrisbeae42b2018-02-15 17:36:33 -080082 template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -080083 void SonameSize();
84
Christopher Ferrisbeae42b2018-02-15 17:36:33 -080085 template <typename ElfInterfaceType>
86 void SonameMissingMap();
87
Christopher Ferris61d40972017-06-12 19:14:20 -070088 template <typename ElfType>
89 void InitHeadersEhFrameTest();
90
91 template <typename ElfType>
92 void InitHeadersDebugFrame();
93
94 template <typename ElfType>
95 void InitHeadersEhFrameFail();
96
97 template <typename ElfType>
98 void InitHeadersDebugFrameFail();
99
Christopher Ferris5acf0692018-08-01 13:10:46 -0700100 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
101 void InitProgramHeadersMalformed();
102
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700103 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
104 void InitSectionHeadersMalformed();
105
Christopher Ferris5acf0692018-08-01 13:10:46 -0700106 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
107 void InitSectionHeadersMalformedSymData();
108
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700109 template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
110 void InitSectionHeaders(uint64_t entry_size);
111
112 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
113 void InitSectionHeadersOffsets();
114
115 template <typename Sym>
116 void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
117 uint64_t sym_offset, const char* name);
118
Christopher Ferris3958f802017-02-01 15:44:40 -0800119 MemoryFake memory_;
120};
121
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700122template <typename Sym>
123void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
124 uint64_t sym_offset, const char* name) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700125 Sym sym = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700126 sym.st_info = STT_FUNC;
127 sym.st_value = value;
128 sym.st_size = size;
129 sym.st_name = name_offset;
130 sym.st_shndx = SHN_COMMON;
131
132 memory_.SetMemory(offset, &sym, sizeof(sym));
133 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
134}
135
Christopher Ferris3958f802017-02-01 15:44:40 -0800136template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
137void ElfInterfaceTest::SinglePtLoad() {
138 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
139
Christopher Ferrisf882a382018-06-22 16:48:02 -0700140 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800141 ehdr.e_phoff = 0x100;
142 ehdr.e_phnum = 1;
143 ehdr.e_phentsize = sizeof(Phdr);
144 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
145
Christopher Ferrisf882a382018-06-22 16:48:02 -0700146 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800147 phdr.p_type = PT_LOAD;
148 phdr.p_vaddr = 0x2000;
149 phdr.p_memsz = 0x10000;
150 phdr.p_flags = PF_R | PF_X;
151 phdr.p_align = 0x1000;
152 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
153
Christopher Ferrise69f4702017-10-19 16:08:58 -0700154 uint64_t load_bias = 0;
155 ASSERT_TRUE(elf->Init(&load_bias));
156 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800157
158 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
159 ASSERT_EQ(1U, pt_loads.size());
160 LoadInfo load_data = pt_loads.at(0);
161 ASSERT_EQ(0U, load_data.offset);
162 ASSERT_EQ(0x2000U, load_data.table_offset);
163 ASSERT_EQ(0x10000U, load_data.table_size);
164}
165
166TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
167 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
168}
169
170TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
171 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
172}
173
174template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
175void ElfInterfaceTest::MultipleExecutablePtLoads() {
176 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
177
Christopher Ferrisf882a382018-06-22 16:48:02 -0700178 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800179 ehdr.e_phoff = 0x100;
180 ehdr.e_phnum = 3;
181 ehdr.e_phentsize = sizeof(Phdr);
182 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
183
Christopher Ferrisf882a382018-06-22 16:48:02 -0700184 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800185 phdr.p_type = PT_LOAD;
186 phdr.p_vaddr = 0x2000;
187 phdr.p_memsz = 0x10000;
188 phdr.p_flags = PF_R | PF_X;
189 phdr.p_align = 0x1000;
190 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
191
192 memset(&phdr, 0, sizeof(phdr));
193 phdr.p_type = PT_LOAD;
194 phdr.p_offset = 0x1000;
195 phdr.p_vaddr = 0x2001;
196 phdr.p_memsz = 0x10001;
197 phdr.p_flags = PF_R | PF_X;
198 phdr.p_align = 0x1001;
199 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
200
201 memset(&phdr, 0, sizeof(phdr));
202 phdr.p_type = PT_LOAD;
203 phdr.p_offset = 0x2000;
204 phdr.p_vaddr = 0x2002;
205 phdr.p_memsz = 0x10002;
206 phdr.p_flags = PF_R | PF_X;
207 phdr.p_align = 0x1002;
208 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
209
Christopher Ferrise69f4702017-10-19 16:08:58 -0700210 uint64_t load_bias = 0;
211 ASSERT_TRUE(elf->Init(&load_bias));
212 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800213
214 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
215 ASSERT_EQ(3U, pt_loads.size());
216
217 LoadInfo load_data = pt_loads.at(0);
218 ASSERT_EQ(0U, load_data.offset);
219 ASSERT_EQ(0x2000U, load_data.table_offset);
220 ASSERT_EQ(0x10000U, load_data.table_size);
221
222 load_data = pt_loads.at(0x1000);
223 ASSERT_EQ(0x1000U, load_data.offset);
224 ASSERT_EQ(0x2001U, load_data.table_offset);
225 ASSERT_EQ(0x10001U, load_data.table_size);
226
227 load_data = pt_loads.at(0x2000);
228 ASSERT_EQ(0x2000U, load_data.offset);
229 ASSERT_EQ(0x2002U, load_data.table_offset);
230 ASSERT_EQ(0x10002U, load_data.table_size);
231}
232
233TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
234 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
235}
236
237TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
238 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
239}
240
241template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
242void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
243 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
244
Christopher Ferrisf882a382018-06-22 16:48:02 -0700245 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800246 ehdr.e_phoff = 0x100;
247 ehdr.e_phnum = 3;
248 ehdr.e_phentsize = sizeof(Phdr) + 100;
249 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
250
Christopher Ferrisf882a382018-06-22 16:48:02 -0700251 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800252 phdr.p_type = PT_LOAD;
253 phdr.p_vaddr = 0x2000;
254 phdr.p_memsz = 0x10000;
255 phdr.p_flags = PF_R | PF_X;
256 phdr.p_align = 0x1000;
257 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
258
259 memset(&phdr, 0, sizeof(phdr));
260 phdr.p_type = PT_LOAD;
261 phdr.p_offset = 0x1000;
262 phdr.p_vaddr = 0x2001;
263 phdr.p_memsz = 0x10001;
264 phdr.p_flags = PF_R | PF_X;
265 phdr.p_align = 0x1001;
266 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
267
268 memset(&phdr, 0, sizeof(phdr));
269 phdr.p_type = PT_LOAD;
270 phdr.p_offset = 0x2000;
271 phdr.p_vaddr = 0x2002;
272 phdr.p_memsz = 0x10002;
273 phdr.p_flags = PF_R | PF_X;
274 phdr.p_align = 0x1002;
275 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
276
Christopher Ferrise69f4702017-10-19 16:08:58 -0700277 uint64_t load_bias = 0;
278 ASSERT_TRUE(elf->Init(&load_bias));
279 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800280
281 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
282 ASSERT_EQ(3U, pt_loads.size());
283
284 LoadInfo load_data = pt_loads.at(0);
285 ASSERT_EQ(0U, load_data.offset);
286 ASSERT_EQ(0x2000U, load_data.table_offset);
287 ASSERT_EQ(0x10000U, load_data.table_size);
288
289 load_data = pt_loads.at(0x1000);
290 ASSERT_EQ(0x1000U, load_data.offset);
291 ASSERT_EQ(0x2001U, load_data.table_offset);
292 ASSERT_EQ(0x10001U, load_data.table_size);
293
294 load_data = pt_loads.at(0x2000);
295 ASSERT_EQ(0x2000U, load_data.offset);
296 ASSERT_EQ(0x2002U, load_data.table_offset);
297 ASSERT_EQ(0x10002U, load_data.table_size);
298}
299
300TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
301 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
302 ElfInterface32>();
303}
304
305TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
306 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
307 ElfInterface64>();
308}
309
310template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
311void ElfInterfaceTest::NonExecutablePtLoads() {
312 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
313
Christopher Ferrisf882a382018-06-22 16:48:02 -0700314 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800315 ehdr.e_phoff = 0x100;
316 ehdr.e_phnum = 3;
317 ehdr.e_phentsize = sizeof(Phdr);
318 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
319
Christopher Ferrisf882a382018-06-22 16:48:02 -0700320 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800321 phdr.p_type = PT_LOAD;
322 phdr.p_vaddr = 0x2000;
323 phdr.p_memsz = 0x10000;
324 phdr.p_flags = PF_R;
325 phdr.p_align = 0x1000;
326 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
327
328 memset(&phdr, 0, sizeof(phdr));
329 phdr.p_type = PT_LOAD;
330 phdr.p_offset = 0x1000;
331 phdr.p_vaddr = 0x2001;
332 phdr.p_memsz = 0x10001;
333 phdr.p_flags = PF_R | PF_X;
334 phdr.p_align = 0x1001;
335 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
336
337 memset(&phdr, 0, sizeof(phdr));
338 phdr.p_type = PT_LOAD;
339 phdr.p_offset = 0x2000;
340 phdr.p_vaddr = 0x2002;
341 phdr.p_memsz = 0x10002;
342 phdr.p_flags = PF_R;
343 phdr.p_align = 0x1002;
344 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
345
Christopher Ferrise69f4702017-10-19 16:08:58 -0700346 uint64_t load_bias = 0;
347 ASSERT_TRUE(elf->Init(&load_bias));
348 EXPECT_EQ(0U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800349
350 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
351 ASSERT_EQ(1U, pt_loads.size());
352
353 LoadInfo load_data = pt_loads.at(0x1000);
354 ASSERT_EQ(0x1000U, load_data.offset);
355 ASSERT_EQ(0x2001U, load_data.table_offset);
356 ASSERT_EQ(0x10001U, load_data.table_size);
357}
358
359TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
360 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
361}
362
363TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
364 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
365}
366
367template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
368void ElfInterfaceTest::ManyPhdrs() {
369 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
370
Christopher Ferrisf882a382018-06-22 16:48:02 -0700371 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800372 ehdr.e_phoff = 0x100;
373 ehdr.e_phnum = 7;
374 ehdr.e_phentsize = sizeof(Phdr);
375 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
376
Christopher Ferris3958f802017-02-01 15:44:40 -0800377 uint64_t phdr_offset = 0x100;
378
Christopher Ferrisf882a382018-06-22 16:48:02 -0700379 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800380 phdr.p_type = PT_LOAD;
381 phdr.p_vaddr = 0x2000;
382 phdr.p_memsz = 0x10000;
383 phdr.p_flags = PF_R | PF_X;
384 phdr.p_align = 0x1000;
385 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
386 phdr_offset += sizeof(phdr);
387
388 memset(&phdr, 0, sizeof(phdr));
389 phdr.p_type = PT_GNU_EH_FRAME;
390 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
391 phdr_offset += sizeof(phdr);
392
393 memset(&phdr, 0, sizeof(phdr));
394 phdr.p_type = PT_DYNAMIC;
395 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
396 phdr_offset += sizeof(phdr);
397
398 memset(&phdr, 0, sizeof(phdr));
399 phdr.p_type = PT_INTERP;
400 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
401 phdr_offset += sizeof(phdr);
402
403 memset(&phdr, 0, sizeof(phdr));
404 phdr.p_type = PT_NOTE;
405 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
406 phdr_offset += sizeof(phdr);
407
408 memset(&phdr, 0, sizeof(phdr));
409 phdr.p_type = PT_SHLIB;
410 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
411 phdr_offset += sizeof(phdr);
412
413 memset(&phdr, 0, sizeof(phdr));
414 phdr.p_type = PT_GNU_EH_FRAME;
415 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
416 phdr_offset += sizeof(phdr);
417
Christopher Ferrise69f4702017-10-19 16:08:58 -0700418 uint64_t load_bias = 0;
419 ASSERT_TRUE(elf->Init(&load_bias));
420 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800421
422 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
423 ASSERT_EQ(1U, pt_loads.size());
424
425 LoadInfo load_data = pt_loads.at(0);
426 ASSERT_EQ(0U, load_data.offset);
427 ASSERT_EQ(0x2000U, load_data.table_offset);
428 ASSERT_EQ(0x10000U, load_data.table_size);
429}
430
431TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
432 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
433}
434
435TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
436 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
437}
438
439TEST_F(ElfInterfaceTest, elf32_arm) {
440 ElfInterfaceArm elf_arm(&memory_);
441
Christopher Ferrisf882a382018-06-22 16:48:02 -0700442 Elf32_Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800443 ehdr.e_phoff = 0x100;
444 ehdr.e_phnum = 1;
445 ehdr.e_phentsize = sizeof(Elf32_Phdr);
446 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
447
Christopher Ferrisf882a382018-06-22 16:48:02 -0700448 Elf32_Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800449 phdr.p_type = PT_ARM_EXIDX;
Christopher Ferrisf882a382018-06-22 16:48:02 -0700450 phdr.p_offset = 0x2000;
451 phdr.p_filesz = 16;
Christopher Ferris3958f802017-02-01 15:44:40 -0800452 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
453
454 // Add arm exidx entries.
455 memory_.SetData32(0x2000, 0x1000);
456 memory_.SetData32(0x2008, 0x1000);
457
Christopher Ferrise69f4702017-10-19 16:08:58 -0700458 uint64_t load_bias = 0;
459 ASSERT_TRUE(elf_arm.Init(&load_bias));
460 EXPECT_EQ(0U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800461
462 std::vector<uint32_t> entries;
463 for (auto addr : elf_arm) {
464 entries.push_back(addr);
465 }
466 ASSERT_EQ(2U, entries.size());
467 ASSERT_EQ(0x3000U, entries[0]);
468 ASSERT_EQ(0x3008U, entries[1]);
469
470 ASSERT_EQ(0x2000U, elf_arm.start_offset());
471 ASSERT_EQ(2U, elf_arm.total_entries());
472}
473
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800474template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
475void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700476 Ehdr ehdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800477 ehdr.e_shoff = 0x200;
478 ehdr.e_shnum = 2;
479 ehdr.e_shentsize = sizeof(Shdr);
Christopher Ferris3958f802017-02-01 15:44:40 -0800480 ehdr.e_phoff = 0x100;
481 ehdr.e_phnum = 1;
482 ehdr.e_phentsize = sizeof(Phdr);
483 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
484
Christopher Ferrisf882a382018-06-22 16:48:02 -0700485 Shdr shdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800486 shdr.sh_type = SHT_STRTAB;
487 if (test_type == SONAME_MISSING_MAP) {
488 shdr.sh_addr = 0x20100;
489 } else {
490 shdr.sh_addr = 0x10100;
491 }
492 shdr.sh_offset = 0x10000;
493 memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
494
Christopher Ferrisf882a382018-06-22 16:48:02 -0700495 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800496 phdr.p_type = PT_DYNAMIC;
497 phdr.p_offset = 0x2000;
498 phdr.p_memsz = sizeof(Dyn) * 3;
499 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
500
501 uint64_t offset = 0x2000;
502 Dyn dyn;
503
504 dyn.d_tag = DT_STRTAB;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800505 dyn.d_un.d_ptr = 0x10100;
Christopher Ferris3958f802017-02-01 15:44:40 -0800506 memory_.SetMemory(offset, &dyn, sizeof(dyn));
507 offset += sizeof(dyn);
508
509 dyn.d_tag = DT_STRSZ;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800510 if (test_type == SONAME_DTSIZE_SMALL) {
511 dyn.d_un.d_val = 0x10;
512 } else {
513 dyn.d_un.d_val = 0x1000;
514 }
Christopher Ferris3958f802017-02-01 15:44:40 -0800515 memory_.SetMemory(offset, &dyn, sizeof(dyn));
516 offset += sizeof(dyn);
517
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800518 if (test_type == SONAME_DTNULL_AFTER) {
519 dyn.d_tag = DT_NULL;
520 memory_.SetMemory(offset, &dyn, sizeof(dyn));
521 offset += sizeof(dyn);
522 }
523
Christopher Ferris3958f802017-02-01 15:44:40 -0800524 dyn.d_tag = DT_SONAME;
525 dyn.d_un.d_val = 0x10;
526 memory_.SetMemory(offset, &dyn, sizeof(dyn));
527 offset += sizeof(dyn);
528
529 dyn.d_tag = DT_NULL;
530 memory_.SetMemory(offset, &dyn, sizeof(dyn));
531
532 SetStringMemory(0x10010, "fake_soname.so");
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800533}
534
535template <typename ElfInterfaceType>
536void ElfInterfaceTest::Soname() {
537 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
Christopher Ferris3958f802017-02-01 15:44:40 -0800538
Christopher Ferrise69f4702017-10-19 16:08:58 -0700539 uint64_t load_bias = 0;
540 ASSERT_TRUE(elf->Init(&load_bias));
541 EXPECT_EQ(0U, load_bias);
542
Christopher Ferris3958f802017-02-01 15:44:40 -0800543 std::string name;
544 ASSERT_TRUE(elf->GetSoname(&name));
545 ASSERT_STREQ("fake_soname.so", name.c_str());
546}
547
548TEST_F(ElfInterfaceTest, elf32_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800549 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
550 Soname<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800551}
552
553TEST_F(ElfInterfaceTest, elf64_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800554 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
555 Soname<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800556}
557
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800558template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800559void ElfInterfaceTest::SonameAfterDtNull() {
560 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
561
Christopher Ferrise69f4702017-10-19 16:08:58 -0700562 uint64_t load_bias = 0;
563 ASSERT_TRUE(elf->Init(&load_bias));
564 EXPECT_EQ(0U, load_bias);
565
Christopher Ferris3958f802017-02-01 15:44:40 -0800566 std::string name;
567 ASSERT_FALSE(elf->GetSoname(&name));
568}
569
570TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800571 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
572 SonameAfterDtNull<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800573}
574
575TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800576 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
577 SonameAfterDtNull<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800578}
579
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800580template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800581void ElfInterfaceTest::SonameSize() {
582 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
583
Christopher Ferrise69f4702017-10-19 16:08:58 -0700584 uint64_t load_bias = 0;
585 ASSERT_TRUE(elf->Init(&load_bias));
586 EXPECT_EQ(0U, load_bias);
587
Christopher Ferris3958f802017-02-01 15:44:40 -0800588 std::string name;
589 ASSERT_FALSE(elf->GetSoname(&name));
590}
591
592TEST_F(ElfInterfaceTest, elf32_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800593 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
594 SonameSize<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800595}
596
597TEST_F(ElfInterfaceTest, elf64_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800598 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
599 SonameSize<ElfInterface64>();
600}
601
602// Verify that there is no map from STRTAB in the dynamic section to a
603// STRTAB entry in the section headers.
604template <typename ElfInterfaceType>
605void ElfInterfaceTest::SonameMissingMap() {
606 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
607
608 uint64_t load_bias = 0;
609 ASSERT_TRUE(elf->Init(&load_bias));
610 EXPECT_EQ(0U, load_bias);
611
612 std::string name;
613 ASSERT_FALSE(elf->GetSoname(&name));
614}
615
616TEST_F(ElfInterfaceTest, elf32_soname_missing_map) {
617 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
618 SonameMissingMap<ElfInterface32>();
619}
620
621TEST_F(ElfInterfaceTest, elf64_soname_missing_map) {
622 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
623 SonameMissingMap<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800624}
Christopher Ferris61d40972017-06-12 19:14:20 -0700625
Christopher Ferris61d40972017-06-12 19:14:20 -0700626template <typename ElfType>
627void ElfInterfaceTest::InitHeadersEhFrameTest() {
628 ElfType elf(&memory_);
629
Christopher Ferrise69f4702017-10-19 16:08:58 -0700630 elf.FakeSetEhFrameOffset(0x10000);
631 elf.FakeSetEhFrameSize(0);
632 elf.FakeSetDebugFrameOffset(0);
633 elf.FakeSetDebugFrameSize(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700634
635 memory_.SetMemory(0x10000,
636 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
637 memory_.SetData32(0x10004, 0x500);
638 memory_.SetData32(0x10008, 250);
639
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700640 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700641
642 EXPECT_FALSE(elf.eh_frame() == nullptr);
643 EXPECT_TRUE(elf.debug_frame() == nullptr);
644}
645
646TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700647 InitHeadersEhFrameTest<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700648}
649
650TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700651 InitHeadersEhFrameTest<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700652}
653
654template <typename ElfType>
655void ElfInterfaceTest::InitHeadersDebugFrame() {
656 ElfType elf(&memory_);
657
Christopher Ferrise69f4702017-10-19 16:08:58 -0700658 elf.FakeSetEhFrameOffset(0);
659 elf.FakeSetEhFrameSize(0);
660 elf.FakeSetDebugFrameOffset(0x5000);
661 elf.FakeSetDebugFrameSize(0x200);
Christopher Ferris61d40972017-06-12 19:14:20 -0700662
663 memory_.SetData32(0x5000, 0xfc);
664 memory_.SetData32(0x5004, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -0700665 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
Christopher Ferris61d40972017-06-12 19:14:20 -0700666
667 memory_.SetData32(0x5100, 0xfc);
668 memory_.SetData32(0x5104, 0);
669 memory_.SetData32(0x5108, 0x1500);
670 memory_.SetData32(0x510c, 0x200);
671
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700672 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700673
674 EXPECT_TRUE(elf.eh_frame() == nullptr);
675 EXPECT_FALSE(elf.debug_frame() == nullptr);
676}
677
678TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700679 InitHeadersDebugFrame<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700680}
681
682TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700683 InitHeadersDebugFrame<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700684}
685
Christopher Ferris5acf0692018-08-01 13:10:46 -0700686template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
687void ElfInterfaceTest::InitProgramHeadersMalformed() {
688 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
689
690 Ehdr ehdr = {};
691 ehdr.e_phoff = 0x100;
692 ehdr.e_phnum = 3;
693 ehdr.e_phentsize = sizeof(Phdr);
694 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
695
696 uint64_t load_bias = 0;
697 ASSERT_TRUE(elf->Init(&load_bias));
698 EXPECT_EQ(0U, load_bias);
699}
700
701TEST_F(ElfInterfaceTest, init_program_headers_malformed32) {
702 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
703}
704
705TEST_F(ElfInterfaceTest, init_program_headers_malformed64) {
706 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
707}
708
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700709template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
710void ElfInterfaceTest::InitSectionHeadersMalformed() {
711 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
712
Christopher Ferrisf882a382018-06-22 16:48:02 -0700713 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700714 ehdr.e_shoff = 0x1000;
715 ehdr.e_shnum = 10;
716 ehdr.e_shentsize = sizeof(Shdr);
717 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
718
Christopher Ferrise69f4702017-10-19 16:08:58 -0700719 uint64_t load_bias = 0;
720 ASSERT_TRUE(elf->Init(&load_bias));
721 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700722}
723
724TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
725 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
726}
727
728TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
729 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
730}
731
Christopher Ferris5acf0692018-08-01 13:10:46 -0700732template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
733void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
734 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
735
736 uint64_t offset = 0x1000;
737
738 Ehdr ehdr = {};
739 ehdr.e_shoff = offset;
740 ehdr.e_shnum = 5;
741 ehdr.e_shentsize = sizeof(Shdr);
742 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
743
744 offset += ehdr.e_shentsize;
745
746 Shdr shdr = {};
747 shdr.sh_type = SHT_SYMTAB;
748 shdr.sh_link = 4;
749 shdr.sh_addr = 0x5000;
750 shdr.sh_offset = 0x5000;
751 shdr.sh_entsize = 0x100;
752 shdr.sh_size = shdr.sh_entsize * 10;
753 memory_.SetMemory(offset, &shdr, sizeof(shdr));
754 offset += ehdr.e_shentsize;
755
756 memset(&shdr, 0, sizeof(shdr));
757 shdr.sh_type = SHT_DYNSYM;
758 shdr.sh_link = 10;
759 shdr.sh_addr = 0x6000;
760 shdr.sh_offset = 0x6000;
761 shdr.sh_entsize = 0x100;
762 shdr.sh_size = shdr.sh_entsize * 10;
763 memory_.SetMemory(offset, &shdr, sizeof(shdr));
764 offset += ehdr.e_shentsize;
765
766 memset(&shdr, 0, sizeof(shdr));
767 shdr.sh_type = SHT_DYNSYM;
768 shdr.sh_link = 2;
769 shdr.sh_addr = 0x6000;
770 shdr.sh_offset = 0x6000;
771 shdr.sh_entsize = 0x100;
772 shdr.sh_size = shdr.sh_entsize * 10;
773 memory_.SetMemory(offset, &shdr, sizeof(shdr));
774 offset += ehdr.e_shentsize;
775
776 // The string data for the entries.
777 memset(&shdr, 0, sizeof(shdr));
778 shdr.sh_type = SHT_STRTAB;
779 shdr.sh_name = 0x20000;
780 shdr.sh_offset = 0xf000;
781 shdr.sh_size = 0x1000;
782 memory_.SetMemory(offset, &shdr, sizeof(shdr));
783 offset += ehdr.e_shentsize;
784
785 uint64_t load_bias = 0;
786 ASSERT_TRUE(elf->Init(&load_bias));
787 EXPECT_EQ(0U, load_bias);
788 EXPECT_EQ(0U, elf->debug_frame_offset());
789 EXPECT_EQ(0U, elf->debug_frame_size());
790 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
791 EXPECT_EQ(0U, elf->gnu_debugdata_size());
792
793 std::string name;
794 uint64_t name_offset;
795 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
796}
797
798TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata32) {
799 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
800}
801
802TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata64) {
803 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
804}
805
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700806template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
807void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
808 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
809
810 uint64_t offset = 0x1000;
811
Christopher Ferrisf882a382018-06-22 16:48:02 -0700812 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700813 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700814 ehdr.e_shnum = 5;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700815 ehdr.e_shentsize = entry_size;
816 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
817
818 offset += ehdr.e_shentsize;
819
Christopher Ferrisf882a382018-06-22 16:48:02 -0700820 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700821 shdr.sh_type = SHT_SYMTAB;
822 shdr.sh_link = 4;
823 shdr.sh_addr = 0x5000;
824 shdr.sh_offset = 0x5000;
825 shdr.sh_entsize = sizeof(Sym);
826 shdr.sh_size = shdr.sh_entsize * 10;
827 memory_.SetMemory(offset, &shdr, sizeof(shdr));
828 offset += ehdr.e_shentsize;
829
830 memset(&shdr, 0, sizeof(shdr));
831 shdr.sh_type = SHT_DYNSYM;
832 shdr.sh_link = 4;
833 shdr.sh_addr = 0x6000;
834 shdr.sh_offset = 0x6000;
835 shdr.sh_entsize = sizeof(Sym);
836 shdr.sh_size = shdr.sh_entsize * 10;
837 memory_.SetMemory(offset, &shdr, sizeof(shdr));
838 offset += ehdr.e_shentsize;
839
840 memset(&shdr, 0, sizeof(shdr));
841 shdr.sh_type = SHT_PROGBITS;
842 shdr.sh_name = 0xa000;
843 memory_.SetMemory(offset, &shdr, sizeof(shdr));
844 offset += ehdr.e_shentsize;
845
846 // The string data for the entries.
847 memset(&shdr, 0, sizeof(shdr));
848 shdr.sh_type = SHT_STRTAB;
849 shdr.sh_name = 0x20000;
850 shdr.sh_offset = 0xf000;
851 shdr.sh_size = 0x1000;
852 memory_.SetMemory(offset, &shdr, sizeof(shdr));
853 offset += ehdr.e_shentsize;
854
855 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
856 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
857
Christopher Ferrise69f4702017-10-19 16:08:58 -0700858 uint64_t load_bias = 0;
859 ASSERT_TRUE(elf->Init(&load_bias));
860 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700861 EXPECT_EQ(0U, elf->debug_frame_offset());
862 EXPECT_EQ(0U, elf->debug_frame_size());
863 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
864 EXPECT_EQ(0U, elf->gnu_debugdata_size());
865
866 // Look in the first symbol table.
867 std::string name;
868 uint64_t name_offset;
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700869 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700870 EXPECT_EQ("function_one", name);
871 EXPECT_EQ(16U, name_offset);
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700872 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700873 EXPECT_EQ("function_two", name);
874 EXPECT_EQ(32U, name_offset);
875}
876
877TEST_F(ElfInterfaceTest, init_section_headers32) {
878 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
879}
880
881TEST_F(ElfInterfaceTest, init_section_headers64) {
882 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
883}
884
885TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
886 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
887}
888
889TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
890 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
891}
892
893template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
894void ElfInterfaceTest::InitSectionHeadersOffsets() {
895 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
896
897 uint64_t offset = 0x2000;
898
Christopher Ferrisf882a382018-06-22 16:48:02 -0700899 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700900 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700901 ehdr.e_shnum = 6;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700902 ehdr.e_shentsize = sizeof(Shdr);
903 ehdr.e_shstrndx = 2;
904 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
905
906 offset += ehdr.e_shentsize;
907
Christopher Ferrisf882a382018-06-22 16:48:02 -0700908 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700909 shdr.sh_type = SHT_PROGBITS;
910 shdr.sh_link = 2;
911 shdr.sh_name = 0x200;
912 shdr.sh_addr = 0x5000;
913 shdr.sh_offset = 0x5000;
914 shdr.sh_entsize = 0x100;
915 shdr.sh_size = 0x800;
916 memory_.SetMemory(offset, &shdr, sizeof(shdr));
917 offset += ehdr.e_shentsize;
918
919 // The string data for section header names.
920 memset(&shdr, 0, sizeof(shdr));
921 shdr.sh_type = SHT_STRTAB;
922 shdr.sh_name = 0x20000;
923 shdr.sh_offset = 0xf000;
924 shdr.sh_size = 0x1000;
925 memory_.SetMemory(offset, &shdr, sizeof(shdr));
926 offset += ehdr.e_shentsize;
927
928 memset(&shdr, 0, sizeof(shdr));
929 shdr.sh_type = SHT_PROGBITS;
930 shdr.sh_link = 2;
931 shdr.sh_name = 0x100;
932 shdr.sh_addr = 0x6000;
933 shdr.sh_offset = 0x6000;
934 shdr.sh_entsize = 0x100;
935 shdr.sh_size = 0x500;
936 memory_.SetMemory(offset, &shdr, sizeof(shdr));
937 offset += ehdr.e_shentsize;
938
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700939 memset(&shdr, 0, sizeof(shdr));
940 shdr.sh_type = SHT_PROGBITS;
941 shdr.sh_link = 2;
942 shdr.sh_name = 0x300;
943 shdr.sh_addr = 0x7000;
944 shdr.sh_offset = 0x7000;
945 shdr.sh_entsize = 0x100;
946 shdr.sh_size = 0x800;
947 memory_.SetMemory(offset, &shdr, sizeof(shdr));
948 offset += ehdr.e_shentsize;
949
950 memset(&shdr, 0, sizeof(shdr));
951 shdr.sh_type = SHT_PROGBITS;
952 shdr.sh_link = 2;
953 shdr.sh_name = 0x400;
954 shdr.sh_addr = 0x6000;
955 shdr.sh_offset = 0xa000;
956 shdr.sh_entsize = 0x100;
957 shdr.sh_size = 0xf00;
958 memory_.SetMemory(offset, &shdr, sizeof(shdr));
959 offset += ehdr.e_shentsize;
960
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700961 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
962 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700963 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
964 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700965
Christopher Ferrise69f4702017-10-19 16:08:58 -0700966 uint64_t load_bias = 0;
967 ASSERT_TRUE(elf->Init(&load_bias));
968 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700969 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
970 EXPECT_EQ(0x500U, elf->debug_frame_size());
971 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
972 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700973 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
974 EXPECT_EQ(0x800U, elf->eh_frame_size());
975 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
976 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700977}
978
979TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
980 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
981}
982
983TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
984 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
985}
Christopher Ferrisd226a512017-07-14 10:37:19 -0700986
Christopher Ferris150db122017-12-20 18:49:01 -0800987TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
988 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
989
Christopher Ferrisf882a382018-06-22 16:48:02 -0700990 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -0800991 ehdr.e_phoff = 0x100;
992 ehdr.e_phnum = 1;
993 ehdr.e_phentsize = sizeof(Elf32_Phdr);
994 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
995
Christopher Ferrisf882a382018-06-22 16:48:02 -0700996 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -0800997 phdr.p_type = PT_LOAD;
998 phdr.p_vaddr = 0;
999 phdr.p_memsz = 0x10000;
1000 phdr.p_flags = PF_R | PF_X;
1001 phdr.p_align = 0x1000;
1002 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1003
1004 uint64_t load_bias = 0;
1005 ASSERT_TRUE(elf->Init(&load_bias));
1006 EXPECT_EQ(0U, load_bias);
1007 EXPECT_TRUE(elf->IsValidPc(0));
1008 EXPECT_TRUE(elf->IsValidPc(0x5000));
1009 EXPECT_TRUE(elf->IsValidPc(0xffff));
1010 EXPECT_FALSE(elf->IsValidPc(0x10000));
1011}
1012
1013TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1014 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1015
Christopher Ferrisf882a382018-06-22 16:48:02 -07001016 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001017 ehdr.e_phoff = 0x100;
1018 ehdr.e_phnum = 1;
1019 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1020 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1021
Christopher Ferrisf882a382018-06-22 16:48:02 -07001022 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001023 phdr.p_type = PT_LOAD;
1024 phdr.p_vaddr = 0x2000;
1025 phdr.p_memsz = 0x10000;
1026 phdr.p_flags = PF_R | PF_X;
1027 phdr.p_align = 0x1000;
1028 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1029
1030 uint64_t load_bias = 0;
1031 ASSERT_TRUE(elf->Init(&load_bias));
1032 EXPECT_EQ(0x2000U, load_bias);
1033 EXPECT_FALSE(elf->IsValidPc(0));
1034 EXPECT_FALSE(elf->IsValidPc(0x1000));
1035 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1036 EXPECT_TRUE(elf->IsValidPc(0x2000));
1037 EXPECT_TRUE(elf->IsValidPc(0x5000));
1038 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1039 EXPECT_FALSE(elf->IsValidPc(0x12000));
1040}
1041
1042TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1043 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1044
1045 uint64_t sh_offset = 0x100;
1046
Christopher Ferrisf882a382018-06-22 16:48:02 -07001047 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001048 ehdr.e_shstrndx = 1;
1049 ehdr.e_shoff = sh_offset;
1050 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1051 ehdr.e_shnum = 3;
1052 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1053
Christopher Ferrisf882a382018-06-22 16:48:02 -07001054 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001055 shdr.sh_type = SHT_NULL;
1056 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1057
1058 sh_offset += sizeof(shdr);
1059 memset(&shdr, 0, sizeof(shdr));
1060 shdr.sh_type = SHT_STRTAB;
1061 shdr.sh_name = 1;
1062 shdr.sh_offset = 0x500;
1063 shdr.sh_size = 0x100;
1064 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1065 memory_.SetMemory(0x500, ".debug_frame");
1066
1067 sh_offset += sizeof(shdr);
1068 memset(&shdr, 0, sizeof(shdr));
1069 shdr.sh_type = SHT_PROGBITS;
1070 shdr.sh_name = 0;
1071 shdr.sh_addr = 0x600;
1072 shdr.sh_offset = 0x600;
1073 shdr.sh_size = 0x200;
1074 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1075
1076 // CIE 32.
1077 memory_.SetData32(0x600, 0xfc);
1078 memory_.SetData32(0x604, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001079 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001080
1081 // FDE 32.
1082 memory_.SetData32(0x700, 0xfc);
1083 memory_.SetData32(0x704, 0);
1084 memory_.SetData32(0x708, 0x2100);
1085 memory_.SetData32(0x70c, 0x200);
1086
1087 uint64_t load_bias = 0;
1088 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001089 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001090 EXPECT_EQ(0U, load_bias);
1091 EXPECT_FALSE(elf->IsValidPc(0));
1092 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1093 EXPECT_TRUE(elf->IsValidPc(0x2100));
1094 EXPECT_TRUE(elf->IsValidPc(0x2200));
1095 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1096 EXPECT_FALSE(elf->IsValidPc(0x2300));
1097}
1098
1099TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1100 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1101
1102 uint64_t sh_offset = 0x100;
1103
Christopher Ferrisf882a382018-06-22 16:48:02 -07001104 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001105 ehdr.e_shstrndx = 1;
1106 ehdr.e_shoff = sh_offset;
1107 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1108 ehdr.e_shnum = 3;
1109 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1110
Christopher Ferrisf882a382018-06-22 16:48:02 -07001111 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001112 shdr.sh_type = SHT_NULL;
1113 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1114
1115 sh_offset += sizeof(shdr);
1116 memset(&shdr, 0, sizeof(shdr));
1117 shdr.sh_type = SHT_STRTAB;
1118 shdr.sh_name = 1;
1119 shdr.sh_offset = 0x500;
1120 shdr.sh_size = 0x100;
1121 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1122 memory_.SetMemory(0x500, ".eh_frame");
1123
1124 sh_offset += sizeof(shdr);
1125 memset(&shdr, 0, sizeof(shdr));
1126 shdr.sh_type = SHT_PROGBITS;
1127 shdr.sh_name = 0;
1128 shdr.sh_addr = 0x600;
1129 shdr.sh_offset = 0x600;
1130 shdr.sh_size = 0x200;
1131 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1132
1133 // CIE 32.
1134 memory_.SetData32(0x600, 0xfc);
1135 memory_.SetData32(0x604, 0);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001136 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001137
1138 // FDE 32.
1139 memory_.SetData32(0x700, 0xfc);
1140 memory_.SetData32(0x704, 0x104);
1141 memory_.SetData32(0x708, 0x20f8);
1142 memory_.SetData32(0x70c, 0x200);
1143
1144 uint64_t load_bias = 0;
1145 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001146 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001147 EXPECT_EQ(0U, load_bias);
1148 EXPECT_FALSE(elf->IsValidPc(0));
1149 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1150 EXPECT_TRUE(elf->IsValidPc(0x2800));
1151 EXPECT_TRUE(elf->IsValidPc(0x2900));
1152 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1153 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1154}
1155
Christopher Ferrisd226a512017-07-14 10:37:19 -07001156} // namespace unwindstack