blob: 5b2036bdb838794404abfa312f2652047c140210 [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
Florian Mayerda459e52018-11-23 16:56:17 +0000119 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
120 void BuildID();
121
122 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
123 void BuildIDTwoNotes();
124
125 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
126 void BuildIDSectionTooSmallForName();
127
128 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
129 void BuildIDSectionTooSmallForDesc();
130
131 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
132 void BuildIDSectionTooSmallForHeader();
133
Christopher Ferris6c8ac562019-10-02 17:41:16 -0700134 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
135 void CheckLoadBiasInFirstPhdr(uint64_t load_bias);
136
137 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
138 void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, uint64_t load_bias);
139
Christopher Ferris3958f802017-02-01 15:44:40 -0800140 MemoryFake memory_;
141};
142
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700143template <typename Sym>
144void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
145 uint64_t sym_offset, const char* name) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700146 Sym sym = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700147 sym.st_info = STT_FUNC;
148 sym.st_value = value;
149 sym.st_size = size;
150 sym.st_name = name_offset;
151 sym.st_shndx = SHN_COMMON;
152
153 memory_.SetMemory(offset, &sym, sizeof(sym));
154 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
155}
156
Christopher Ferris3958f802017-02-01 15:44:40 -0800157template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
158void ElfInterfaceTest::SinglePtLoad() {
159 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
160
Christopher Ferrisf882a382018-06-22 16:48:02 -0700161 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800162 ehdr.e_phoff = 0x100;
163 ehdr.e_phnum = 1;
164 ehdr.e_phentsize = sizeof(Phdr);
165 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
166
Christopher Ferrisf882a382018-06-22 16:48:02 -0700167 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800168 phdr.p_type = PT_LOAD;
169 phdr.p_vaddr = 0x2000;
170 phdr.p_memsz = 0x10000;
171 phdr.p_flags = PF_R | PF_X;
172 phdr.p_align = 0x1000;
173 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
174
Christopher Ferrise69f4702017-10-19 16:08:58 -0700175 uint64_t load_bias = 0;
176 ASSERT_TRUE(elf->Init(&load_bias));
177 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800178
179 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
180 ASSERT_EQ(1U, pt_loads.size());
181 LoadInfo load_data = pt_loads.at(0);
182 ASSERT_EQ(0U, load_data.offset);
183 ASSERT_EQ(0x2000U, load_data.table_offset);
184 ASSERT_EQ(0x10000U, load_data.table_size);
185}
186
187TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
188 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
189}
190
191TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
192 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
193}
194
195template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
196void ElfInterfaceTest::MultipleExecutablePtLoads() {
197 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
198
Christopher Ferrisf882a382018-06-22 16:48:02 -0700199 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800200 ehdr.e_phoff = 0x100;
201 ehdr.e_phnum = 3;
202 ehdr.e_phentsize = sizeof(Phdr);
203 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
204
Christopher Ferrisf882a382018-06-22 16:48:02 -0700205 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800206 phdr.p_type = PT_LOAD;
207 phdr.p_vaddr = 0x2000;
208 phdr.p_memsz = 0x10000;
209 phdr.p_flags = PF_R | PF_X;
210 phdr.p_align = 0x1000;
211 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
212
213 memset(&phdr, 0, sizeof(phdr));
214 phdr.p_type = PT_LOAD;
215 phdr.p_offset = 0x1000;
216 phdr.p_vaddr = 0x2001;
217 phdr.p_memsz = 0x10001;
218 phdr.p_flags = PF_R | PF_X;
219 phdr.p_align = 0x1001;
220 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
221
222 memset(&phdr, 0, sizeof(phdr));
223 phdr.p_type = PT_LOAD;
224 phdr.p_offset = 0x2000;
225 phdr.p_vaddr = 0x2002;
226 phdr.p_memsz = 0x10002;
227 phdr.p_flags = PF_R | PF_X;
228 phdr.p_align = 0x1002;
229 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
230
Christopher Ferrise69f4702017-10-19 16:08:58 -0700231 uint64_t load_bias = 0;
232 ASSERT_TRUE(elf->Init(&load_bias));
233 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800234
235 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
236 ASSERT_EQ(3U, pt_loads.size());
237
238 LoadInfo load_data = pt_loads.at(0);
239 ASSERT_EQ(0U, load_data.offset);
240 ASSERT_EQ(0x2000U, load_data.table_offset);
241 ASSERT_EQ(0x10000U, load_data.table_size);
242
243 load_data = pt_loads.at(0x1000);
244 ASSERT_EQ(0x1000U, load_data.offset);
245 ASSERT_EQ(0x2001U, load_data.table_offset);
246 ASSERT_EQ(0x10001U, load_data.table_size);
247
248 load_data = pt_loads.at(0x2000);
249 ASSERT_EQ(0x2000U, load_data.offset);
250 ASSERT_EQ(0x2002U, load_data.table_offset);
251 ASSERT_EQ(0x10002U, load_data.table_size);
252}
253
254TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
255 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
256}
257
258TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
259 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
260}
261
262template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
263void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
264 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
265
Christopher Ferrisf882a382018-06-22 16:48:02 -0700266 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800267 ehdr.e_phoff = 0x100;
268 ehdr.e_phnum = 3;
269 ehdr.e_phentsize = sizeof(Phdr) + 100;
270 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
271
Christopher Ferrisf882a382018-06-22 16:48:02 -0700272 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800273 phdr.p_type = PT_LOAD;
274 phdr.p_vaddr = 0x2000;
275 phdr.p_memsz = 0x10000;
276 phdr.p_flags = PF_R | PF_X;
277 phdr.p_align = 0x1000;
278 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
279
280 memset(&phdr, 0, sizeof(phdr));
281 phdr.p_type = PT_LOAD;
282 phdr.p_offset = 0x1000;
283 phdr.p_vaddr = 0x2001;
284 phdr.p_memsz = 0x10001;
285 phdr.p_flags = PF_R | PF_X;
286 phdr.p_align = 0x1001;
287 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
288
289 memset(&phdr, 0, sizeof(phdr));
290 phdr.p_type = PT_LOAD;
291 phdr.p_offset = 0x2000;
292 phdr.p_vaddr = 0x2002;
293 phdr.p_memsz = 0x10002;
294 phdr.p_flags = PF_R | PF_X;
295 phdr.p_align = 0x1002;
296 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
297
Christopher Ferrise69f4702017-10-19 16:08:58 -0700298 uint64_t load_bias = 0;
299 ASSERT_TRUE(elf->Init(&load_bias));
300 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800301
302 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
303 ASSERT_EQ(3U, pt_loads.size());
304
305 LoadInfo load_data = pt_loads.at(0);
306 ASSERT_EQ(0U, load_data.offset);
307 ASSERT_EQ(0x2000U, load_data.table_offset);
308 ASSERT_EQ(0x10000U, load_data.table_size);
309
310 load_data = pt_loads.at(0x1000);
311 ASSERT_EQ(0x1000U, load_data.offset);
312 ASSERT_EQ(0x2001U, load_data.table_offset);
313 ASSERT_EQ(0x10001U, load_data.table_size);
314
315 load_data = pt_loads.at(0x2000);
316 ASSERT_EQ(0x2000U, load_data.offset);
317 ASSERT_EQ(0x2002U, load_data.table_offset);
318 ASSERT_EQ(0x10002U, load_data.table_size);
319}
320
321TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
322 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
323 ElfInterface32>();
324}
325
326TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
327 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
328 ElfInterface64>();
329}
330
331template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
332void ElfInterfaceTest::NonExecutablePtLoads() {
333 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
334
Christopher Ferrisf882a382018-06-22 16:48:02 -0700335 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800336 ehdr.e_phoff = 0x100;
337 ehdr.e_phnum = 3;
338 ehdr.e_phentsize = sizeof(Phdr);
339 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
340
Christopher Ferrisf882a382018-06-22 16:48:02 -0700341 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800342 phdr.p_type = PT_LOAD;
343 phdr.p_vaddr = 0x2000;
344 phdr.p_memsz = 0x10000;
345 phdr.p_flags = PF_R;
346 phdr.p_align = 0x1000;
347 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
348
349 memset(&phdr, 0, sizeof(phdr));
350 phdr.p_type = PT_LOAD;
351 phdr.p_offset = 0x1000;
352 phdr.p_vaddr = 0x2001;
353 phdr.p_memsz = 0x10001;
354 phdr.p_flags = PF_R | PF_X;
355 phdr.p_align = 0x1001;
356 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
357
358 memset(&phdr, 0, sizeof(phdr));
359 phdr.p_type = PT_LOAD;
360 phdr.p_offset = 0x2000;
361 phdr.p_vaddr = 0x2002;
362 phdr.p_memsz = 0x10002;
363 phdr.p_flags = PF_R;
364 phdr.p_align = 0x1002;
365 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
366
Christopher Ferrise69f4702017-10-19 16:08:58 -0700367 uint64_t load_bias = 0;
368 ASSERT_TRUE(elf->Init(&load_bias));
Florian Mayer249c90f2019-07-05 16:48:04 +0100369 EXPECT_EQ(0x1001U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800370
371 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
372 ASSERT_EQ(1U, pt_loads.size());
373
374 LoadInfo load_data = pt_loads.at(0x1000);
375 ASSERT_EQ(0x1000U, load_data.offset);
376 ASSERT_EQ(0x2001U, load_data.table_offset);
377 ASSERT_EQ(0x10001U, load_data.table_size);
378}
379
380TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
381 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
382}
383
384TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
385 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
386}
387
388template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
389void ElfInterfaceTest::ManyPhdrs() {
390 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
391
Christopher Ferrisf882a382018-06-22 16:48:02 -0700392 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800393 ehdr.e_phoff = 0x100;
394 ehdr.e_phnum = 7;
395 ehdr.e_phentsize = sizeof(Phdr);
396 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
397
Christopher Ferris3958f802017-02-01 15:44:40 -0800398 uint64_t phdr_offset = 0x100;
399
Christopher Ferrisf882a382018-06-22 16:48:02 -0700400 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800401 phdr.p_type = PT_LOAD;
402 phdr.p_vaddr = 0x2000;
403 phdr.p_memsz = 0x10000;
404 phdr.p_flags = PF_R | PF_X;
405 phdr.p_align = 0x1000;
406 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
407 phdr_offset += sizeof(phdr);
408
409 memset(&phdr, 0, sizeof(phdr));
410 phdr.p_type = PT_GNU_EH_FRAME;
411 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
412 phdr_offset += sizeof(phdr);
413
414 memset(&phdr, 0, sizeof(phdr));
415 phdr.p_type = PT_DYNAMIC;
416 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
417 phdr_offset += sizeof(phdr);
418
419 memset(&phdr, 0, sizeof(phdr));
420 phdr.p_type = PT_INTERP;
421 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
422 phdr_offset += sizeof(phdr);
423
424 memset(&phdr, 0, sizeof(phdr));
425 phdr.p_type = PT_NOTE;
426 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
427 phdr_offset += sizeof(phdr);
428
429 memset(&phdr, 0, sizeof(phdr));
430 phdr.p_type = PT_SHLIB;
431 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
432 phdr_offset += sizeof(phdr);
433
434 memset(&phdr, 0, sizeof(phdr));
435 phdr.p_type = PT_GNU_EH_FRAME;
436 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
437 phdr_offset += sizeof(phdr);
438
Christopher Ferrise69f4702017-10-19 16:08:58 -0700439 uint64_t load_bias = 0;
440 ASSERT_TRUE(elf->Init(&load_bias));
441 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800442
443 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
444 ASSERT_EQ(1U, pt_loads.size());
445
446 LoadInfo load_data = pt_loads.at(0);
447 ASSERT_EQ(0U, load_data.offset);
448 ASSERT_EQ(0x2000U, load_data.table_offset);
449 ASSERT_EQ(0x10000U, load_data.table_size);
450}
451
452TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
453 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
454}
455
456TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
457 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
458}
459
460TEST_F(ElfInterfaceTest, elf32_arm) {
461 ElfInterfaceArm elf_arm(&memory_);
462
Christopher Ferrisf882a382018-06-22 16:48:02 -0700463 Elf32_Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800464 ehdr.e_phoff = 0x100;
465 ehdr.e_phnum = 1;
466 ehdr.e_phentsize = sizeof(Elf32_Phdr);
467 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
468
Christopher Ferrisf882a382018-06-22 16:48:02 -0700469 Elf32_Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800470 phdr.p_type = PT_ARM_EXIDX;
Christopher Ferrisf882a382018-06-22 16:48:02 -0700471 phdr.p_offset = 0x2000;
472 phdr.p_filesz = 16;
Christopher Ferris3958f802017-02-01 15:44:40 -0800473 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
474
475 // Add arm exidx entries.
476 memory_.SetData32(0x2000, 0x1000);
477 memory_.SetData32(0x2008, 0x1000);
478
Christopher Ferrise69f4702017-10-19 16:08:58 -0700479 uint64_t load_bias = 0;
480 ASSERT_TRUE(elf_arm.Init(&load_bias));
481 EXPECT_EQ(0U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800482
483 std::vector<uint32_t> entries;
484 for (auto addr : elf_arm) {
485 entries.push_back(addr);
486 }
487 ASSERT_EQ(2U, entries.size());
488 ASSERT_EQ(0x3000U, entries[0]);
489 ASSERT_EQ(0x3008U, entries[1]);
490
491 ASSERT_EQ(0x2000U, elf_arm.start_offset());
492 ASSERT_EQ(2U, elf_arm.total_entries());
493}
494
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800495template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
496void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700497 Ehdr ehdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800498 ehdr.e_shoff = 0x200;
499 ehdr.e_shnum = 2;
500 ehdr.e_shentsize = sizeof(Shdr);
Christopher Ferris3958f802017-02-01 15:44:40 -0800501 ehdr.e_phoff = 0x100;
502 ehdr.e_phnum = 1;
503 ehdr.e_phentsize = sizeof(Phdr);
504 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
505
Christopher Ferrisf882a382018-06-22 16:48:02 -0700506 Shdr shdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800507 shdr.sh_type = SHT_STRTAB;
508 if (test_type == SONAME_MISSING_MAP) {
509 shdr.sh_addr = 0x20100;
510 } else {
511 shdr.sh_addr = 0x10100;
512 }
513 shdr.sh_offset = 0x10000;
514 memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
515
Christopher Ferrisf882a382018-06-22 16:48:02 -0700516 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800517 phdr.p_type = PT_DYNAMIC;
518 phdr.p_offset = 0x2000;
519 phdr.p_memsz = sizeof(Dyn) * 3;
520 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
521
522 uint64_t offset = 0x2000;
523 Dyn dyn;
524
525 dyn.d_tag = DT_STRTAB;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800526 dyn.d_un.d_ptr = 0x10100;
Christopher Ferris3958f802017-02-01 15:44:40 -0800527 memory_.SetMemory(offset, &dyn, sizeof(dyn));
528 offset += sizeof(dyn);
529
530 dyn.d_tag = DT_STRSZ;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800531 if (test_type == SONAME_DTSIZE_SMALL) {
532 dyn.d_un.d_val = 0x10;
533 } else {
534 dyn.d_un.d_val = 0x1000;
535 }
Christopher Ferris3958f802017-02-01 15:44:40 -0800536 memory_.SetMemory(offset, &dyn, sizeof(dyn));
537 offset += sizeof(dyn);
538
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800539 if (test_type == SONAME_DTNULL_AFTER) {
540 dyn.d_tag = DT_NULL;
541 memory_.SetMemory(offset, &dyn, sizeof(dyn));
542 offset += sizeof(dyn);
543 }
544
Christopher Ferris3958f802017-02-01 15:44:40 -0800545 dyn.d_tag = DT_SONAME;
546 dyn.d_un.d_val = 0x10;
547 memory_.SetMemory(offset, &dyn, sizeof(dyn));
548 offset += sizeof(dyn);
549
550 dyn.d_tag = DT_NULL;
551 memory_.SetMemory(offset, &dyn, sizeof(dyn));
552
553 SetStringMemory(0x10010, "fake_soname.so");
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800554}
555
556template <typename ElfInterfaceType>
557void ElfInterfaceTest::Soname() {
558 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
Christopher Ferris3958f802017-02-01 15:44:40 -0800559
Christopher Ferrise69f4702017-10-19 16:08:58 -0700560 uint64_t load_bias = 0;
561 ASSERT_TRUE(elf->Init(&load_bias));
562 EXPECT_EQ(0U, load_bias);
563
Christopher Ferris02a6c442019-03-11 14:43:33 -0700564 ASSERT_EQ("fake_soname.so", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800565}
566
567TEST_F(ElfInterfaceTest, elf32_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800568 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
569 Soname<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800570}
571
572TEST_F(ElfInterfaceTest, elf64_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800573 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
574 Soname<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800575}
576
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800577template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800578void ElfInterfaceTest::SonameAfterDtNull() {
579 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
580
Christopher Ferrise69f4702017-10-19 16:08:58 -0700581 uint64_t load_bias = 0;
582 ASSERT_TRUE(elf->Init(&load_bias));
583 EXPECT_EQ(0U, load_bias);
584
Christopher Ferris02a6c442019-03-11 14:43:33 -0700585 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800586}
587
588TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800589 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
590 SonameAfterDtNull<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800591}
592
593TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800594 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
595 SonameAfterDtNull<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800596}
597
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800598template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800599void ElfInterfaceTest::SonameSize() {
600 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
601
Christopher Ferrise69f4702017-10-19 16:08:58 -0700602 uint64_t load_bias = 0;
603 ASSERT_TRUE(elf->Init(&load_bias));
604 EXPECT_EQ(0U, load_bias);
605
Christopher Ferris02a6c442019-03-11 14:43:33 -0700606 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800607}
608
609TEST_F(ElfInterfaceTest, elf32_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800610 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
611 SonameSize<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800612}
613
614TEST_F(ElfInterfaceTest, elf64_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800615 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
616 SonameSize<ElfInterface64>();
617}
618
619// Verify that there is no map from STRTAB in the dynamic section to a
620// STRTAB entry in the section headers.
621template <typename ElfInterfaceType>
622void ElfInterfaceTest::SonameMissingMap() {
623 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
624
625 uint64_t load_bias = 0;
626 ASSERT_TRUE(elf->Init(&load_bias));
627 EXPECT_EQ(0U, load_bias);
628
Christopher Ferris02a6c442019-03-11 14:43:33 -0700629 ASSERT_EQ("", elf->GetSoname());
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800630}
631
632TEST_F(ElfInterfaceTest, elf32_soname_missing_map) {
633 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
634 SonameMissingMap<ElfInterface32>();
635}
636
637TEST_F(ElfInterfaceTest, elf64_soname_missing_map) {
638 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
639 SonameMissingMap<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800640}
Christopher Ferris61d40972017-06-12 19:14:20 -0700641
Christopher Ferris61d40972017-06-12 19:14:20 -0700642template <typename ElfType>
643void ElfInterfaceTest::InitHeadersEhFrameTest() {
644 ElfType elf(&memory_);
645
Christopher Ferrise69f4702017-10-19 16:08:58 -0700646 elf.FakeSetEhFrameOffset(0x10000);
647 elf.FakeSetEhFrameSize(0);
648 elf.FakeSetDebugFrameOffset(0);
649 elf.FakeSetDebugFrameSize(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700650
651 memory_.SetMemory(0x10000,
652 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
653 memory_.SetData32(0x10004, 0x500);
654 memory_.SetData32(0x10008, 250);
655
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700656 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700657
658 EXPECT_FALSE(elf.eh_frame() == nullptr);
659 EXPECT_TRUE(elf.debug_frame() == nullptr);
660}
661
662TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700663 InitHeadersEhFrameTest<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700664}
665
666TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700667 InitHeadersEhFrameTest<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700668}
669
670template <typename ElfType>
671void ElfInterfaceTest::InitHeadersDebugFrame() {
672 ElfType elf(&memory_);
673
Christopher Ferrise69f4702017-10-19 16:08:58 -0700674 elf.FakeSetEhFrameOffset(0);
675 elf.FakeSetEhFrameSize(0);
676 elf.FakeSetDebugFrameOffset(0x5000);
677 elf.FakeSetDebugFrameSize(0x200);
Christopher Ferris61d40972017-06-12 19:14:20 -0700678
679 memory_.SetData32(0x5000, 0xfc);
680 memory_.SetData32(0x5004, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -0700681 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
Christopher Ferris61d40972017-06-12 19:14:20 -0700682
683 memory_.SetData32(0x5100, 0xfc);
684 memory_.SetData32(0x5104, 0);
685 memory_.SetData32(0x5108, 0x1500);
686 memory_.SetData32(0x510c, 0x200);
687
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700688 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700689
690 EXPECT_TRUE(elf.eh_frame() == nullptr);
691 EXPECT_FALSE(elf.debug_frame() == nullptr);
692}
693
694TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700695 InitHeadersDebugFrame<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700696}
697
698TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700699 InitHeadersDebugFrame<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700700}
701
Christopher Ferris5acf0692018-08-01 13:10:46 -0700702template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
703void ElfInterfaceTest::InitProgramHeadersMalformed() {
704 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
705
706 Ehdr ehdr = {};
707 ehdr.e_phoff = 0x100;
708 ehdr.e_phnum = 3;
709 ehdr.e_phentsize = sizeof(Phdr);
710 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
711
712 uint64_t load_bias = 0;
713 ASSERT_TRUE(elf->Init(&load_bias));
714 EXPECT_EQ(0U, load_bias);
715}
716
717TEST_F(ElfInterfaceTest, init_program_headers_malformed32) {
718 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
719}
720
721TEST_F(ElfInterfaceTest, init_program_headers_malformed64) {
722 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
723}
724
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700725template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
726void ElfInterfaceTest::InitSectionHeadersMalformed() {
727 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
728
Christopher Ferrisf882a382018-06-22 16:48:02 -0700729 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700730 ehdr.e_shoff = 0x1000;
731 ehdr.e_shnum = 10;
732 ehdr.e_shentsize = sizeof(Shdr);
733 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
734
Christopher Ferrise69f4702017-10-19 16:08:58 -0700735 uint64_t load_bias = 0;
736 ASSERT_TRUE(elf->Init(&load_bias));
737 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700738}
739
740TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
741 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
742}
743
744TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
745 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
746}
747
Christopher Ferris5acf0692018-08-01 13:10:46 -0700748template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
749void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
750 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
751
752 uint64_t offset = 0x1000;
753
754 Ehdr ehdr = {};
755 ehdr.e_shoff = offset;
756 ehdr.e_shnum = 5;
757 ehdr.e_shentsize = sizeof(Shdr);
758 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
759
760 offset += ehdr.e_shentsize;
761
762 Shdr shdr = {};
763 shdr.sh_type = SHT_SYMTAB;
764 shdr.sh_link = 4;
765 shdr.sh_addr = 0x5000;
766 shdr.sh_offset = 0x5000;
767 shdr.sh_entsize = 0x100;
768 shdr.sh_size = shdr.sh_entsize * 10;
769 memory_.SetMemory(offset, &shdr, sizeof(shdr));
770 offset += ehdr.e_shentsize;
771
772 memset(&shdr, 0, sizeof(shdr));
773 shdr.sh_type = SHT_DYNSYM;
774 shdr.sh_link = 10;
775 shdr.sh_addr = 0x6000;
776 shdr.sh_offset = 0x6000;
777 shdr.sh_entsize = 0x100;
778 shdr.sh_size = shdr.sh_entsize * 10;
779 memory_.SetMemory(offset, &shdr, sizeof(shdr));
780 offset += ehdr.e_shentsize;
781
782 memset(&shdr, 0, sizeof(shdr));
783 shdr.sh_type = SHT_DYNSYM;
784 shdr.sh_link = 2;
785 shdr.sh_addr = 0x6000;
786 shdr.sh_offset = 0x6000;
787 shdr.sh_entsize = 0x100;
788 shdr.sh_size = shdr.sh_entsize * 10;
789 memory_.SetMemory(offset, &shdr, sizeof(shdr));
790 offset += ehdr.e_shentsize;
791
792 // The string data for the entries.
793 memset(&shdr, 0, sizeof(shdr));
794 shdr.sh_type = SHT_STRTAB;
795 shdr.sh_name = 0x20000;
796 shdr.sh_offset = 0xf000;
797 shdr.sh_size = 0x1000;
798 memory_.SetMemory(offset, &shdr, sizeof(shdr));
799 offset += ehdr.e_shentsize;
800
801 uint64_t load_bias = 0;
802 ASSERT_TRUE(elf->Init(&load_bias));
803 EXPECT_EQ(0U, load_bias);
804 EXPECT_EQ(0U, elf->debug_frame_offset());
805 EXPECT_EQ(0U, elf->debug_frame_size());
806 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
807 EXPECT_EQ(0U, elf->gnu_debugdata_size());
808
809 std::string name;
810 uint64_t name_offset;
811 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
812}
813
814TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata32) {
815 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
816}
817
818TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata64) {
819 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
820}
821
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700822template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
823void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
824 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
825
826 uint64_t offset = 0x1000;
827
Christopher Ferrisf882a382018-06-22 16:48:02 -0700828 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700829 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700830 ehdr.e_shnum = 5;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700831 ehdr.e_shentsize = entry_size;
832 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
833
834 offset += ehdr.e_shentsize;
835
Christopher Ferrisf882a382018-06-22 16:48:02 -0700836 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700837 shdr.sh_type = SHT_SYMTAB;
838 shdr.sh_link = 4;
839 shdr.sh_addr = 0x5000;
840 shdr.sh_offset = 0x5000;
841 shdr.sh_entsize = sizeof(Sym);
842 shdr.sh_size = shdr.sh_entsize * 10;
843 memory_.SetMemory(offset, &shdr, sizeof(shdr));
844 offset += ehdr.e_shentsize;
845
846 memset(&shdr, 0, sizeof(shdr));
847 shdr.sh_type = SHT_DYNSYM;
848 shdr.sh_link = 4;
849 shdr.sh_addr = 0x6000;
850 shdr.sh_offset = 0x6000;
851 shdr.sh_entsize = sizeof(Sym);
852 shdr.sh_size = shdr.sh_entsize * 10;
853 memory_.SetMemory(offset, &shdr, sizeof(shdr));
854 offset += ehdr.e_shentsize;
855
856 memset(&shdr, 0, sizeof(shdr));
857 shdr.sh_type = SHT_PROGBITS;
858 shdr.sh_name = 0xa000;
859 memory_.SetMemory(offset, &shdr, sizeof(shdr));
860 offset += ehdr.e_shentsize;
861
862 // The string data for the entries.
863 memset(&shdr, 0, sizeof(shdr));
864 shdr.sh_type = SHT_STRTAB;
865 shdr.sh_name = 0x20000;
866 shdr.sh_offset = 0xf000;
867 shdr.sh_size = 0x1000;
868 memory_.SetMemory(offset, &shdr, sizeof(shdr));
869 offset += ehdr.e_shentsize;
870
871 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
872 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
873
Christopher Ferrise69f4702017-10-19 16:08:58 -0700874 uint64_t load_bias = 0;
875 ASSERT_TRUE(elf->Init(&load_bias));
876 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700877 EXPECT_EQ(0U, elf->debug_frame_offset());
878 EXPECT_EQ(0U, elf->debug_frame_size());
879 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
880 EXPECT_EQ(0U, elf->gnu_debugdata_size());
881
882 // Look in the first symbol table.
883 std::string name;
884 uint64_t name_offset;
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700885 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700886 EXPECT_EQ("function_one", name);
887 EXPECT_EQ(16U, name_offset);
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700888 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700889 EXPECT_EQ("function_two", name);
890 EXPECT_EQ(32U, name_offset);
891}
892
893TEST_F(ElfInterfaceTest, init_section_headers32) {
894 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
895}
896
897TEST_F(ElfInterfaceTest, init_section_headers64) {
898 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
899}
900
901TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
902 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
903}
904
905TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
906 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
907}
908
909template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
910void ElfInterfaceTest::InitSectionHeadersOffsets() {
911 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
912
913 uint64_t offset = 0x2000;
914
Christopher Ferrisf882a382018-06-22 16:48:02 -0700915 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700916 ehdr.e_shoff = offset;
Florian Mayerda459e52018-11-23 16:56:17 +0000917 ehdr.e_shnum = 7;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700918 ehdr.e_shentsize = sizeof(Shdr);
919 ehdr.e_shstrndx = 2;
920 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
921
922 offset += ehdr.e_shentsize;
923
Christopher Ferrisf882a382018-06-22 16:48:02 -0700924 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700925 shdr.sh_type = SHT_PROGBITS;
926 shdr.sh_link = 2;
927 shdr.sh_name = 0x200;
928 shdr.sh_addr = 0x5000;
929 shdr.sh_offset = 0x5000;
930 shdr.sh_entsize = 0x100;
931 shdr.sh_size = 0x800;
932 memory_.SetMemory(offset, &shdr, sizeof(shdr));
933 offset += ehdr.e_shentsize;
934
935 // The string data for section header names.
936 memset(&shdr, 0, sizeof(shdr));
937 shdr.sh_type = SHT_STRTAB;
938 shdr.sh_name = 0x20000;
939 shdr.sh_offset = 0xf000;
940 shdr.sh_size = 0x1000;
941 memory_.SetMemory(offset, &shdr, sizeof(shdr));
942 offset += ehdr.e_shentsize;
943
944 memset(&shdr, 0, sizeof(shdr));
945 shdr.sh_type = SHT_PROGBITS;
946 shdr.sh_link = 2;
947 shdr.sh_name = 0x100;
948 shdr.sh_addr = 0x6000;
949 shdr.sh_offset = 0x6000;
950 shdr.sh_entsize = 0x100;
951 shdr.sh_size = 0x500;
952 memory_.SetMemory(offset, &shdr, sizeof(shdr));
953 offset += ehdr.e_shentsize;
954
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700955 memset(&shdr, 0, sizeof(shdr));
956 shdr.sh_type = SHT_PROGBITS;
957 shdr.sh_link = 2;
958 shdr.sh_name = 0x300;
959 shdr.sh_addr = 0x7000;
960 shdr.sh_offset = 0x7000;
961 shdr.sh_entsize = 0x100;
962 shdr.sh_size = 0x800;
963 memory_.SetMemory(offset, &shdr, sizeof(shdr));
964 offset += ehdr.e_shentsize;
965
966 memset(&shdr, 0, sizeof(shdr));
967 shdr.sh_type = SHT_PROGBITS;
968 shdr.sh_link = 2;
969 shdr.sh_name = 0x400;
970 shdr.sh_addr = 0x6000;
971 shdr.sh_offset = 0xa000;
972 shdr.sh_entsize = 0x100;
973 shdr.sh_size = 0xf00;
974 memory_.SetMemory(offset, &shdr, sizeof(shdr));
975 offset += ehdr.e_shentsize;
976
Florian Mayerda459e52018-11-23 16:56:17 +0000977 memset(&shdr, 0, sizeof(shdr));
978 shdr.sh_type = SHT_NOTE;
979 shdr.sh_name = 0x500;
980 shdr.sh_offset = 0xb000;
981 shdr.sh_size = 0xf00;
982 memory_.SetMemory(offset, &shdr, sizeof(shdr));
983 offset += ehdr.e_shentsize;
984
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700985 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
986 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700987 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
988 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
Florian Mayerda459e52018-11-23 16:56:17 +0000989 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700990
Christopher Ferrise69f4702017-10-19 16:08:58 -0700991 uint64_t load_bias = 0;
992 ASSERT_TRUE(elf->Init(&load_bias));
993 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700994 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
995 EXPECT_EQ(0x500U, elf->debug_frame_size());
996 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
997 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700998 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
999 EXPECT_EQ(0x800U, elf->eh_frame_size());
1000 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
1001 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
Florian Mayerda459e52018-11-23 16:56:17 +00001002 EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
1003 EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001004}
1005
1006TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
1007 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1008}
1009
1010TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
1011 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1012}
Christopher Ferrisd226a512017-07-14 10:37:19 -07001013
Christopher Ferris150db122017-12-20 18:49:01 -08001014TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
1015 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1016
Christopher Ferrisf882a382018-06-22 16:48:02 -07001017 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001018 ehdr.e_phoff = 0x100;
1019 ehdr.e_phnum = 1;
1020 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1021 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1022
Christopher Ferrisf882a382018-06-22 16:48:02 -07001023 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001024 phdr.p_type = PT_LOAD;
1025 phdr.p_vaddr = 0;
1026 phdr.p_memsz = 0x10000;
1027 phdr.p_flags = PF_R | PF_X;
1028 phdr.p_align = 0x1000;
1029 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1030
1031 uint64_t load_bias = 0;
1032 ASSERT_TRUE(elf->Init(&load_bias));
1033 EXPECT_EQ(0U, load_bias);
1034 EXPECT_TRUE(elf->IsValidPc(0));
1035 EXPECT_TRUE(elf->IsValidPc(0x5000));
1036 EXPECT_TRUE(elf->IsValidPc(0xffff));
1037 EXPECT_FALSE(elf->IsValidPc(0x10000));
1038}
1039
1040TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1041 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1042
Christopher Ferrisf882a382018-06-22 16:48:02 -07001043 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001044 ehdr.e_phoff = 0x100;
1045 ehdr.e_phnum = 1;
1046 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1047 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1048
Christopher Ferrisf882a382018-06-22 16:48:02 -07001049 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001050 phdr.p_type = PT_LOAD;
1051 phdr.p_vaddr = 0x2000;
1052 phdr.p_memsz = 0x10000;
1053 phdr.p_flags = PF_R | PF_X;
1054 phdr.p_align = 0x1000;
1055 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1056
1057 uint64_t load_bias = 0;
1058 ASSERT_TRUE(elf->Init(&load_bias));
1059 EXPECT_EQ(0x2000U, load_bias);
1060 EXPECT_FALSE(elf->IsValidPc(0));
1061 EXPECT_FALSE(elf->IsValidPc(0x1000));
1062 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1063 EXPECT_TRUE(elf->IsValidPc(0x2000));
1064 EXPECT_TRUE(elf->IsValidPc(0x5000));
1065 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1066 EXPECT_FALSE(elf->IsValidPc(0x12000));
1067}
1068
1069TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1070 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1071
1072 uint64_t sh_offset = 0x100;
1073
Christopher Ferrisf882a382018-06-22 16:48:02 -07001074 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001075 ehdr.e_shstrndx = 1;
1076 ehdr.e_shoff = sh_offset;
1077 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1078 ehdr.e_shnum = 3;
1079 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1080
Christopher Ferrisf882a382018-06-22 16:48:02 -07001081 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001082 shdr.sh_type = SHT_NULL;
1083 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1084
1085 sh_offset += sizeof(shdr);
1086 memset(&shdr, 0, sizeof(shdr));
1087 shdr.sh_type = SHT_STRTAB;
1088 shdr.sh_name = 1;
1089 shdr.sh_offset = 0x500;
1090 shdr.sh_size = 0x100;
1091 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1092 memory_.SetMemory(0x500, ".debug_frame");
1093
1094 sh_offset += sizeof(shdr);
1095 memset(&shdr, 0, sizeof(shdr));
1096 shdr.sh_type = SHT_PROGBITS;
1097 shdr.sh_name = 0;
1098 shdr.sh_addr = 0x600;
1099 shdr.sh_offset = 0x600;
1100 shdr.sh_size = 0x200;
1101 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1102
1103 // CIE 32.
1104 memory_.SetData32(0x600, 0xfc);
1105 memory_.SetData32(0x604, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001106 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001107
1108 // FDE 32.
1109 memory_.SetData32(0x700, 0xfc);
1110 memory_.SetData32(0x704, 0);
1111 memory_.SetData32(0x708, 0x2100);
1112 memory_.SetData32(0x70c, 0x200);
1113
1114 uint64_t load_bias = 0;
1115 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001116 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001117 EXPECT_EQ(0U, load_bias);
1118 EXPECT_FALSE(elf->IsValidPc(0));
1119 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1120 EXPECT_TRUE(elf->IsValidPc(0x2100));
1121 EXPECT_TRUE(elf->IsValidPc(0x2200));
1122 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1123 EXPECT_FALSE(elf->IsValidPc(0x2300));
1124}
1125
1126TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1127 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1128
1129 uint64_t sh_offset = 0x100;
1130
Christopher Ferrisf882a382018-06-22 16:48:02 -07001131 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001132 ehdr.e_shstrndx = 1;
1133 ehdr.e_shoff = sh_offset;
1134 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1135 ehdr.e_shnum = 3;
1136 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1137
Christopher Ferrisf882a382018-06-22 16:48:02 -07001138 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001139 shdr.sh_type = SHT_NULL;
1140 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1141
1142 sh_offset += sizeof(shdr);
1143 memset(&shdr, 0, sizeof(shdr));
1144 shdr.sh_type = SHT_STRTAB;
1145 shdr.sh_name = 1;
1146 shdr.sh_offset = 0x500;
1147 shdr.sh_size = 0x100;
1148 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1149 memory_.SetMemory(0x500, ".eh_frame");
1150
1151 sh_offset += sizeof(shdr);
1152 memset(&shdr, 0, sizeof(shdr));
1153 shdr.sh_type = SHT_PROGBITS;
1154 shdr.sh_name = 0;
1155 shdr.sh_addr = 0x600;
1156 shdr.sh_offset = 0x600;
1157 shdr.sh_size = 0x200;
1158 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1159
1160 // CIE 32.
1161 memory_.SetData32(0x600, 0xfc);
1162 memory_.SetData32(0x604, 0);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001163 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001164
1165 // FDE 32.
1166 memory_.SetData32(0x700, 0xfc);
1167 memory_.SetData32(0x704, 0x104);
1168 memory_.SetData32(0x708, 0x20f8);
1169 memory_.SetData32(0x70c, 0x200);
1170
1171 uint64_t load_bias = 0;
1172 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001173 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001174 EXPECT_EQ(0U, load_bias);
1175 EXPECT_FALSE(elf->IsValidPc(0));
1176 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1177 EXPECT_TRUE(elf->IsValidPc(0x2800));
1178 EXPECT_TRUE(elf->IsValidPc(0x2900));
1179 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1180 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1181}
1182
Florian Mayerda459e52018-11-23 16:56:17 +00001183template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1184void ElfInterfaceTest::BuildID() {
1185 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1186
1187 uint64_t offset = 0x2000;
1188
1189 Ehdr ehdr = {};
1190 ehdr.e_shoff = offset;
1191 ehdr.e_shnum = 3;
1192 ehdr.e_shentsize = sizeof(Shdr);
1193 ehdr.e_shstrndx = 2;
1194 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1195
1196 offset += ehdr.e_shentsize;
1197
1198 char note_section[128];
1199 Nhdr note_header = {};
1200 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001201 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001202 note_header.n_type = NT_GNU_BUILD_ID;
1203 memcpy(&note_section, &note_header, sizeof(note_header));
1204 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001205 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001206 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1207 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001208 // This part of the note does not contain any trailing '\0'.
1209 memcpy(&note_section[note_offset], "BUILDID", 7);
1210 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001211
1212 Shdr shdr = {};
1213 shdr.sh_type = SHT_NOTE;
1214 shdr.sh_name = 0x500;
1215 shdr.sh_offset = 0xb000;
1216 shdr.sh_size = sizeof(note_section);
1217 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1218 offset += ehdr.e_shentsize;
1219
1220 // The string data for section header names.
1221 memset(&shdr, 0, sizeof(shdr));
1222 shdr.sh_type = SHT_STRTAB;
1223 shdr.sh_name = 0x20000;
1224 shdr.sh_offset = 0xf000;
1225 shdr.sh_size = 0x1000;
1226 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1227 offset += ehdr.e_shentsize;
1228
1229 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1230 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1231
1232 uint64_t load_bias = 0;
1233 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001234 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001235}
1236
1237template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1238void ElfInterfaceTest::BuildIDTwoNotes() {
1239 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1240
1241 uint64_t offset = 0x2000;
1242
1243 Ehdr ehdr = {};
1244 ehdr.e_shoff = offset;
1245 ehdr.e_shnum = 3;
1246 ehdr.e_shentsize = sizeof(Shdr);
1247 ehdr.e_shstrndx = 2;
1248 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1249
1250 offset += ehdr.e_shentsize;
1251
1252 char note_section[128];
1253 Nhdr note_header = {};
1254 note_header.n_namesz = 8; // "WRONG" aligned to 4
Christopher Ferris1760b452019-04-03 14:14:30 -07001255 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001256 note_header.n_type = NT_GNU_BUILD_ID;
1257 memcpy(&note_section, &note_header, sizeof(note_header));
1258 size_t note_offset = sizeof(note_header);
1259 memcpy(&note_section[note_offset], "WRONG", sizeof("WRONG"));
1260 note_offset += 8;
Christopher Ferris1760b452019-04-03 14:14:30 -07001261 // This part of the note does not contain any trailing '\0'.
1262 memcpy(&note_section[note_offset], "BUILDID", 7);
1263 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001264
1265 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001266 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001267 note_header.n_type = NT_GNU_BUILD_ID;
1268 memcpy(&note_section[note_offset], &note_header, sizeof(note_header));
1269 note_offset += sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001270 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001271 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1272 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001273 // This part of the note does not contain any trailing '\0'.
1274 memcpy(&note_section[note_offset], "BUILDID", 7);
1275 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001276
1277 Shdr shdr = {};
1278 shdr.sh_type = SHT_NOTE;
1279 shdr.sh_name = 0x500;
1280 shdr.sh_offset = 0xb000;
1281 shdr.sh_size = sizeof(note_section);
1282 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1283 offset += ehdr.e_shentsize;
1284
1285 // The string data for section header names.
1286 memset(&shdr, 0, sizeof(shdr));
1287 shdr.sh_type = SHT_STRTAB;
1288 shdr.sh_name = 0x20000;
1289 shdr.sh_offset = 0xf000;
1290 shdr.sh_size = 0x1000;
1291 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1292 offset += ehdr.e_shentsize;
1293
1294 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1295 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1296
1297 uint64_t load_bias = 0;
1298 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001299 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001300}
1301
1302template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1303void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1304 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1305
1306 uint64_t offset = 0x2000;
1307
1308 Ehdr ehdr = {};
1309 ehdr.e_shoff = offset;
1310 ehdr.e_shnum = 3;
1311 ehdr.e_shentsize = sizeof(Shdr);
1312 ehdr.e_shstrndx = 2;
1313 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1314
1315 offset += ehdr.e_shentsize;
1316
1317 char note_section[128];
1318 Nhdr note_header = {};
1319 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001320 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001321 note_header.n_type = NT_GNU_BUILD_ID;
1322 memcpy(&note_section, &note_header, sizeof(note_header));
1323 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001324 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001325 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1326 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001327 // This part of the note does not contain any trailing '\0'.
1328 memcpy(&note_section[note_offset], "BUILDID", 7);
1329 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001330
1331 Shdr shdr = {};
1332 shdr.sh_type = SHT_NOTE;
1333 shdr.sh_name = 0x500;
1334 shdr.sh_offset = 0xb000;
1335 shdr.sh_size = sizeof(note_header) + 1;
1336 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1337 offset += ehdr.e_shentsize;
1338
1339 // The string data for section header names.
1340 memset(&shdr, 0, sizeof(shdr));
1341 shdr.sh_type = SHT_STRTAB;
1342 shdr.sh_name = 0x20000;
1343 shdr.sh_offset = 0xf000;
1344 shdr.sh_size = 0x1000;
1345 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1346 offset += ehdr.e_shentsize;
1347
1348 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1349 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1350
1351 uint64_t load_bias = 0;
1352 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001353 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001354}
1355
1356template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1357void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1358 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1359
1360 uint64_t offset = 0x2000;
1361
1362 Ehdr ehdr = {};
1363 ehdr.e_shoff = offset;
1364 ehdr.e_shnum = 3;
1365 ehdr.e_shentsize = sizeof(Shdr);
1366 ehdr.e_shstrndx = 2;
1367 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1368
1369 offset += ehdr.e_shentsize;
1370
1371 char note_section[128];
1372 Nhdr note_header = {};
1373 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001374 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001375 note_header.n_type = NT_GNU_BUILD_ID;
1376 memcpy(&note_section, &note_header, sizeof(note_header));
1377 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001378 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001379 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1380 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001381 // This part of the note does not contain any trailing '\0'.
1382 memcpy(&note_section[note_offset], "BUILDID", 7);
1383 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001384
1385 Shdr shdr = {};
1386 shdr.sh_type = SHT_NOTE;
1387 shdr.sh_name = 0x500;
1388 shdr.sh_offset = 0xb000;
1389 shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1390 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1391 offset += ehdr.e_shentsize;
1392
1393 // The string data for section header names.
1394 memset(&shdr, 0, sizeof(shdr));
1395 shdr.sh_type = SHT_STRTAB;
1396 shdr.sh_name = 0x20000;
1397 shdr.sh_offset = 0xf000;
1398 shdr.sh_size = 0x1000;
1399 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1400 offset += ehdr.e_shentsize;
1401
1402 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1403 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1404
1405 uint64_t load_bias = 0;
1406 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001407 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001408}
1409
1410template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1411void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1412 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1413
1414 uint64_t offset = 0x2000;
1415
1416 Ehdr ehdr = {};
1417 ehdr.e_shoff = offset;
1418 ehdr.e_shnum = 3;
1419 ehdr.e_shentsize = sizeof(Shdr);
1420 ehdr.e_shstrndx = 2;
1421 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1422
1423 offset += ehdr.e_shentsize;
1424
1425 char note_section[128];
1426 Nhdr note_header = {};
1427 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001428 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001429 note_header.n_type = NT_GNU_BUILD_ID;
1430 memcpy(&note_section, &note_header, sizeof(note_header));
1431 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001432 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001433 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1434 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001435 // This part of the note does not contain any trailing '\0'.
1436 memcpy(&note_section[note_offset], "BUILDID", 7);
1437 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001438
1439 Shdr shdr = {};
1440 shdr.sh_type = SHT_NOTE;
1441 shdr.sh_name = 0x500;
1442 shdr.sh_offset = 0xb000;
1443 shdr.sh_size = sizeof(note_header) - 1;
1444 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1445 offset += ehdr.e_shentsize;
1446
1447 // The string data for section header names.
1448 memset(&shdr, 0, sizeof(shdr));
1449 shdr.sh_type = SHT_STRTAB;
1450 shdr.sh_name = 0x20000;
1451 shdr.sh_offset = 0xf000;
1452 shdr.sh_size = 0x1000;
1453 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1454 offset += ehdr.e_shentsize;
1455
1456 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1457 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1458
1459 uint64_t load_bias = 0;
1460 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001461 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001462}
1463
1464TEST_F(ElfInterfaceTest, build_id32) {
1465 BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1466}
1467
1468TEST_F(ElfInterfaceTest, build_id64) {
1469 BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1470}
1471
1472TEST_F(ElfInterfaceTest, build_id_two_notes32) {
1473 BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1474}
1475
1476TEST_F(ElfInterfaceTest, build_id_two_notes64) {
1477 BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1478}
1479
1480TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name32) {
1481 BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1482}
1483
1484TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name64) {
1485 BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1486}
1487
1488TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc32) {
1489 BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1490}
1491
1492TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc64) {
1493 BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1494}
1495
1496TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header32) {
1497 BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1498}
1499
1500TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header64) {
1501 BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1502}
1503
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001504template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
1505void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(uint64_t load_bias) {
1506 Ehdr ehdr = {};
1507 ehdr.e_phoff = 0x100;
1508 ehdr.e_phnum = 2;
1509 ehdr.e_phentsize = sizeof(Phdr);
1510 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1511
1512 Phdr phdr = {};
1513 phdr.p_type = PT_LOAD;
1514 phdr.p_offset = 0;
1515 phdr.p_vaddr = load_bias;
1516 phdr.p_memsz = 0x10000;
1517 phdr.p_flags = PF_R | PF_X;
1518 phdr.p_align = 0x1000;
1519 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1520
1521 memset(&phdr, 0, sizeof(phdr));
1522 phdr.p_type = PT_LOAD;
1523 phdr.p_offset = 0x1000;
1524 phdr.p_memsz = 0x2000;
1525 phdr.p_flags = PF_R | PF_X;
1526 phdr.p_align = 0x1000;
1527 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1528
1529 uint64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
1530 ASSERT_EQ(load_bias, static_load_bias);
1531
1532 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1533 uint64_t init_load_bias = 0;
1534 ASSERT_TRUE(elf->Init(&init_load_bias));
1535 ASSERT_EQ(init_load_bias, static_load_bias);
1536}
1537
1538TEST_F(ElfInterfaceTest, get_load_bias_zero_32) {
1539 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0);
1540}
1541
1542TEST_F(ElfInterfaceTest, get_load_bias_zero_64) {
1543 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0);
1544}
1545
1546TEST_F(ElfInterfaceTest, get_load_bias_non_zero_32) {
1547 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000);
1548}
1549
1550TEST_F(ElfInterfaceTest, get_load_bias_non_zero_64) {
1551 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000);
1552}
1553
1554template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
1555void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr,
1556 uint64_t load_bias) {
1557 Ehdr ehdr = {};
1558 ehdr.e_phoff = 0x100;
1559 ehdr.e_phnum = 3;
1560 ehdr.e_phentsize = sizeof(Phdr);
1561 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1562
1563 Phdr phdr = {};
1564 phdr.p_type = PT_LOAD;
1565 phdr.p_memsz = 0x10000;
1566 phdr.p_flags = PF_R;
1567 phdr.p_align = 0x1000;
1568 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1569
1570 memset(&phdr, 0, sizeof(phdr));
1571 phdr.p_type = PT_LOAD;
1572 phdr.p_offset = offset;
1573 phdr.p_vaddr = vaddr;
1574 phdr.p_memsz = 0x2000;
1575 phdr.p_flags = PF_R | PF_X;
1576 phdr.p_align = 0x1000;
1577 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1578
1579 // Second executable load should be ignored for load bias computation.
1580 memset(&phdr, 0, sizeof(phdr));
1581 phdr.p_type = PT_LOAD;
1582 phdr.p_offset = 0x1234;
1583 phdr.p_vaddr = 0x2000;
1584 phdr.p_memsz = 0x2000;
1585 phdr.p_flags = PF_R | PF_X;
1586 phdr.p_align = 0x1000;
1587 memory_.SetMemory(0x200 + sizeof(phdr), &phdr, sizeof(phdr));
1588
1589 uint64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
1590 ASSERT_EQ(load_bias, static_load_bias);
1591
1592 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1593 uint64_t init_load_bias = 0;
1594 ASSERT_TRUE(elf->Init(&init_load_bias));
1595 ASSERT_EQ(init_load_bias, static_load_bias);
1596}
1597
1598TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_32) {
1599 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x1000, 0);
1600}
1601
1602TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_64) {
1603 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x1000, 0);
1604}
1605
1606TEST_F(ElfInterfaceTest, get_load_bias_exec_non_zero_32) {
1607 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x4000, 0x3000);
1608}
1609
1610TEST_F(ElfInterfaceTest, get_load_bias_exec_non_zero_64) {
1611 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x4000, 0x3000);
1612}
1613
1614TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_from_error_32) {
1615 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, 0);
1616}
1617
1618TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_from_error_64) {
1619 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, 0);
1620}
1621
Christopher Ferrisd226a512017-07-14 10:37:19 -07001622} // namespace unwindstack