blob: 6023dc4b82c23878d800055a69c993608e26f4fe [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 Ferris3958f802017-02-01 15:44:40 -0800134 MemoryFake memory_;
135};
136
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700137template <typename Sym>
138void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
139 uint64_t sym_offset, const char* name) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700140 Sym sym = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700141 sym.st_info = STT_FUNC;
142 sym.st_value = value;
143 sym.st_size = size;
144 sym.st_name = name_offset;
145 sym.st_shndx = SHN_COMMON;
146
147 memory_.SetMemory(offset, &sym, sizeof(sym));
148 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
149}
150
Christopher Ferris3958f802017-02-01 15:44:40 -0800151template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
152void ElfInterfaceTest::SinglePtLoad() {
153 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
154
Christopher Ferrisf882a382018-06-22 16:48:02 -0700155 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800156 ehdr.e_phoff = 0x100;
157 ehdr.e_phnum = 1;
158 ehdr.e_phentsize = sizeof(Phdr);
159 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
160
Christopher Ferrisf882a382018-06-22 16:48:02 -0700161 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800162 phdr.p_type = PT_LOAD;
163 phdr.p_vaddr = 0x2000;
164 phdr.p_memsz = 0x10000;
165 phdr.p_flags = PF_R | PF_X;
166 phdr.p_align = 0x1000;
167 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
168
Christopher Ferrise69f4702017-10-19 16:08:58 -0700169 uint64_t load_bias = 0;
170 ASSERT_TRUE(elf->Init(&load_bias));
171 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800172
173 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
174 ASSERT_EQ(1U, pt_loads.size());
175 LoadInfo load_data = pt_loads.at(0);
176 ASSERT_EQ(0U, load_data.offset);
177 ASSERT_EQ(0x2000U, load_data.table_offset);
178 ASSERT_EQ(0x10000U, load_data.table_size);
179}
180
181TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
182 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
183}
184
185TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
186 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
187}
188
189template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
190void ElfInterfaceTest::MultipleExecutablePtLoads() {
191 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
192
Christopher Ferrisf882a382018-06-22 16:48:02 -0700193 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800194 ehdr.e_phoff = 0x100;
195 ehdr.e_phnum = 3;
196 ehdr.e_phentsize = sizeof(Phdr);
197 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
198
Christopher Ferrisf882a382018-06-22 16:48:02 -0700199 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800200 phdr.p_type = PT_LOAD;
201 phdr.p_vaddr = 0x2000;
202 phdr.p_memsz = 0x10000;
203 phdr.p_flags = PF_R | PF_X;
204 phdr.p_align = 0x1000;
205 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
206
207 memset(&phdr, 0, sizeof(phdr));
208 phdr.p_type = PT_LOAD;
209 phdr.p_offset = 0x1000;
210 phdr.p_vaddr = 0x2001;
211 phdr.p_memsz = 0x10001;
212 phdr.p_flags = PF_R | PF_X;
213 phdr.p_align = 0x1001;
214 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
215
216 memset(&phdr, 0, sizeof(phdr));
217 phdr.p_type = PT_LOAD;
218 phdr.p_offset = 0x2000;
219 phdr.p_vaddr = 0x2002;
220 phdr.p_memsz = 0x10002;
221 phdr.p_flags = PF_R | PF_X;
222 phdr.p_align = 0x1002;
223 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
224
Christopher Ferrise69f4702017-10-19 16:08:58 -0700225 uint64_t load_bias = 0;
226 ASSERT_TRUE(elf->Init(&load_bias));
227 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800228
229 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
230 ASSERT_EQ(3U, pt_loads.size());
231
232 LoadInfo load_data = pt_loads.at(0);
233 ASSERT_EQ(0U, load_data.offset);
234 ASSERT_EQ(0x2000U, load_data.table_offset);
235 ASSERT_EQ(0x10000U, load_data.table_size);
236
237 load_data = pt_loads.at(0x1000);
238 ASSERT_EQ(0x1000U, load_data.offset);
239 ASSERT_EQ(0x2001U, load_data.table_offset);
240 ASSERT_EQ(0x10001U, load_data.table_size);
241
242 load_data = pt_loads.at(0x2000);
243 ASSERT_EQ(0x2000U, load_data.offset);
244 ASSERT_EQ(0x2002U, load_data.table_offset);
245 ASSERT_EQ(0x10002U, load_data.table_size);
246}
247
248TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
249 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
250}
251
252TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
253 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
254}
255
256template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
257void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
258 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
259
Christopher Ferrisf882a382018-06-22 16:48:02 -0700260 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800261 ehdr.e_phoff = 0x100;
262 ehdr.e_phnum = 3;
263 ehdr.e_phentsize = sizeof(Phdr) + 100;
264 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
265
Christopher Ferrisf882a382018-06-22 16:48:02 -0700266 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800267 phdr.p_type = PT_LOAD;
268 phdr.p_vaddr = 0x2000;
269 phdr.p_memsz = 0x10000;
270 phdr.p_flags = PF_R | PF_X;
271 phdr.p_align = 0x1000;
272 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
273
274 memset(&phdr, 0, sizeof(phdr));
275 phdr.p_type = PT_LOAD;
276 phdr.p_offset = 0x1000;
277 phdr.p_vaddr = 0x2001;
278 phdr.p_memsz = 0x10001;
279 phdr.p_flags = PF_R | PF_X;
280 phdr.p_align = 0x1001;
281 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
282
283 memset(&phdr, 0, sizeof(phdr));
284 phdr.p_type = PT_LOAD;
285 phdr.p_offset = 0x2000;
286 phdr.p_vaddr = 0x2002;
287 phdr.p_memsz = 0x10002;
288 phdr.p_flags = PF_R | PF_X;
289 phdr.p_align = 0x1002;
290 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
291
Christopher Ferrise69f4702017-10-19 16:08:58 -0700292 uint64_t load_bias = 0;
293 ASSERT_TRUE(elf->Init(&load_bias));
294 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800295
296 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
297 ASSERT_EQ(3U, pt_loads.size());
298
299 LoadInfo load_data = pt_loads.at(0);
300 ASSERT_EQ(0U, load_data.offset);
301 ASSERT_EQ(0x2000U, load_data.table_offset);
302 ASSERT_EQ(0x10000U, load_data.table_size);
303
304 load_data = pt_loads.at(0x1000);
305 ASSERT_EQ(0x1000U, load_data.offset);
306 ASSERT_EQ(0x2001U, load_data.table_offset);
307 ASSERT_EQ(0x10001U, load_data.table_size);
308
309 load_data = pt_loads.at(0x2000);
310 ASSERT_EQ(0x2000U, load_data.offset);
311 ASSERT_EQ(0x2002U, load_data.table_offset);
312 ASSERT_EQ(0x10002U, load_data.table_size);
313}
314
315TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
316 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
317 ElfInterface32>();
318}
319
320TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
321 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
322 ElfInterface64>();
323}
324
325template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
326void ElfInterfaceTest::NonExecutablePtLoads() {
327 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
328
Christopher Ferrisf882a382018-06-22 16:48:02 -0700329 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800330 ehdr.e_phoff = 0x100;
331 ehdr.e_phnum = 3;
332 ehdr.e_phentsize = sizeof(Phdr);
333 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
334
Christopher Ferrisf882a382018-06-22 16:48:02 -0700335 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800336 phdr.p_type = PT_LOAD;
337 phdr.p_vaddr = 0x2000;
338 phdr.p_memsz = 0x10000;
339 phdr.p_flags = PF_R;
340 phdr.p_align = 0x1000;
341 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
342
343 memset(&phdr, 0, sizeof(phdr));
344 phdr.p_type = PT_LOAD;
345 phdr.p_offset = 0x1000;
346 phdr.p_vaddr = 0x2001;
347 phdr.p_memsz = 0x10001;
348 phdr.p_flags = PF_R | PF_X;
349 phdr.p_align = 0x1001;
350 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
351
352 memset(&phdr, 0, sizeof(phdr));
353 phdr.p_type = PT_LOAD;
354 phdr.p_offset = 0x2000;
355 phdr.p_vaddr = 0x2002;
356 phdr.p_memsz = 0x10002;
357 phdr.p_flags = PF_R;
358 phdr.p_align = 0x1002;
359 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
360
Christopher Ferrise69f4702017-10-19 16:08:58 -0700361 uint64_t load_bias = 0;
362 ASSERT_TRUE(elf->Init(&load_bias));
363 EXPECT_EQ(0U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800364
365 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
366 ASSERT_EQ(1U, pt_loads.size());
367
368 LoadInfo load_data = pt_loads.at(0x1000);
369 ASSERT_EQ(0x1000U, load_data.offset);
370 ASSERT_EQ(0x2001U, load_data.table_offset);
371 ASSERT_EQ(0x10001U, load_data.table_size);
372}
373
374TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
375 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
376}
377
378TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
379 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
380}
381
382template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
383void ElfInterfaceTest::ManyPhdrs() {
384 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
385
Christopher Ferrisf882a382018-06-22 16:48:02 -0700386 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800387 ehdr.e_phoff = 0x100;
388 ehdr.e_phnum = 7;
389 ehdr.e_phentsize = sizeof(Phdr);
390 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
391
Christopher Ferris3958f802017-02-01 15:44:40 -0800392 uint64_t phdr_offset = 0x100;
393
Christopher Ferrisf882a382018-06-22 16:48:02 -0700394 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800395 phdr.p_type = PT_LOAD;
396 phdr.p_vaddr = 0x2000;
397 phdr.p_memsz = 0x10000;
398 phdr.p_flags = PF_R | PF_X;
399 phdr.p_align = 0x1000;
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_GNU_EH_FRAME;
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_DYNAMIC;
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_INTERP;
415 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
416 phdr_offset += sizeof(phdr);
417
418 memset(&phdr, 0, sizeof(phdr));
419 phdr.p_type = PT_NOTE;
420 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
421 phdr_offset += sizeof(phdr);
422
423 memset(&phdr, 0, sizeof(phdr));
424 phdr.p_type = PT_SHLIB;
425 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
426 phdr_offset += sizeof(phdr);
427
428 memset(&phdr, 0, sizeof(phdr));
429 phdr.p_type = PT_GNU_EH_FRAME;
430 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
431 phdr_offset += sizeof(phdr);
432
Christopher Ferrise69f4702017-10-19 16:08:58 -0700433 uint64_t load_bias = 0;
434 ASSERT_TRUE(elf->Init(&load_bias));
435 EXPECT_EQ(0x2000U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800436
437 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
438 ASSERT_EQ(1U, pt_loads.size());
439
440 LoadInfo load_data = pt_loads.at(0);
441 ASSERT_EQ(0U, load_data.offset);
442 ASSERT_EQ(0x2000U, load_data.table_offset);
443 ASSERT_EQ(0x10000U, load_data.table_size);
444}
445
446TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
447 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
448}
449
450TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
451 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
452}
453
454TEST_F(ElfInterfaceTest, elf32_arm) {
455 ElfInterfaceArm elf_arm(&memory_);
456
Christopher Ferrisf882a382018-06-22 16:48:02 -0700457 Elf32_Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800458 ehdr.e_phoff = 0x100;
459 ehdr.e_phnum = 1;
460 ehdr.e_phentsize = sizeof(Elf32_Phdr);
461 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
462
Christopher Ferrisf882a382018-06-22 16:48:02 -0700463 Elf32_Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800464 phdr.p_type = PT_ARM_EXIDX;
Christopher Ferrisf882a382018-06-22 16:48:02 -0700465 phdr.p_offset = 0x2000;
466 phdr.p_filesz = 16;
Christopher Ferris3958f802017-02-01 15:44:40 -0800467 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
468
469 // Add arm exidx entries.
470 memory_.SetData32(0x2000, 0x1000);
471 memory_.SetData32(0x2008, 0x1000);
472
Christopher Ferrise69f4702017-10-19 16:08:58 -0700473 uint64_t load_bias = 0;
474 ASSERT_TRUE(elf_arm.Init(&load_bias));
475 EXPECT_EQ(0U, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800476
477 std::vector<uint32_t> entries;
478 for (auto addr : elf_arm) {
479 entries.push_back(addr);
480 }
481 ASSERT_EQ(2U, entries.size());
482 ASSERT_EQ(0x3000U, entries[0]);
483 ASSERT_EQ(0x3008U, entries[1]);
484
485 ASSERT_EQ(0x2000U, elf_arm.start_offset());
486 ASSERT_EQ(2U, elf_arm.total_entries());
487}
488
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800489template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
490void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700491 Ehdr ehdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800492 ehdr.e_shoff = 0x200;
493 ehdr.e_shnum = 2;
494 ehdr.e_shentsize = sizeof(Shdr);
Christopher Ferris3958f802017-02-01 15:44:40 -0800495 ehdr.e_phoff = 0x100;
496 ehdr.e_phnum = 1;
497 ehdr.e_phentsize = sizeof(Phdr);
498 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
499
Christopher Ferrisf882a382018-06-22 16:48:02 -0700500 Shdr shdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800501 shdr.sh_type = SHT_STRTAB;
502 if (test_type == SONAME_MISSING_MAP) {
503 shdr.sh_addr = 0x20100;
504 } else {
505 shdr.sh_addr = 0x10100;
506 }
507 shdr.sh_offset = 0x10000;
508 memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
509
Christopher Ferrisf882a382018-06-22 16:48:02 -0700510 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800511 phdr.p_type = PT_DYNAMIC;
512 phdr.p_offset = 0x2000;
513 phdr.p_memsz = sizeof(Dyn) * 3;
514 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
515
516 uint64_t offset = 0x2000;
517 Dyn dyn;
518
519 dyn.d_tag = DT_STRTAB;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800520 dyn.d_un.d_ptr = 0x10100;
Christopher Ferris3958f802017-02-01 15:44:40 -0800521 memory_.SetMemory(offset, &dyn, sizeof(dyn));
522 offset += sizeof(dyn);
523
524 dyn.d_tag = DT_STRSZ;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800525 if (test_type == SONAME_DTSIZE_SMALL) {
526 dyn.d_un.d_val = 0x10;
527 } else {
528 dyn.d_un.d_val = 0x1000;
529 }
Christopher Ferris3958f802017-02-01 15:44:40 -0800530 memory_.SetMemory(offset, &dyn, sizeof(dyn));
531 offset += sizeof(dyn);
532
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800533 if (test_type == SONAME_DTNULL_AFTER) {
534 dyn.d_tag = DT_NULL;
535 memory_.SetMemory(offset, &dyn, sizeof(dyn));
536 offset += sizeof(dyn);
537 }
538
Christopher Ferris3958f802017-02-01 15:44:40 -0800539 dyn.d_tag = DT_SONAME;
540 dyn.d_un.d_val = 0x10;
541 memory_.SetMemory(offset, &dyn, sizeof(dyn));
542 offset += sizeof(dyn);
543
544 dyn.d_tag = DT_NULL;
545 memory_.SetMemory(offset, &dyn, sizeof(dyn));
546
547 SetStringMemory(0x10010, "fake_soname.so");
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800548}
549
550template <typename ElfInterfaceType>
551void ElfInterfaceTest::Soname() {
552 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
Christopher Ferris3958f802017-02-01 15:44:40 -0800553
Christopher Ferrise69f4702017-10-19 16:08:58 -0700554 uint64_t load_bias = 0;
555 ASSERT_TRUE(elf->Init(&load_bias));
556 EXPECT_EQ(0U, load_bias);
557
Christopher Ferris3958f802017-02-01 15:44:40 -0800558 std::string name;
559 ASSERT_TRUE(elf->GetSoname(&name));
560 ASSERT_STREQ("fake_soname.so", name.c_str());
561}
562
563TEST_F(ElfInterfaceTest, elf32_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800564 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
565 Soname<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800566}
567
568TEST_F(ElfInterfaceTest, elf64_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800569 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
570 Soname<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800571}
572
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800573template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800574void ElfInterfaceTest::SonameAfterDtNull() {
575 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
576
Christopher Ferrise69f4702017-10-19 16:08:58 -0700577 uint64_t load_bias = 0;
578 ASSERT_TRUE(elf->Init(&load_bias));
579 EXPECT_EQ(0U, load_bias);
580
Christopher Ferris3958f802017-02-01 15:44:40 -0800581 std::string name;
582 ASSERT_FALSE(elf->GetSoname(&name));
583}
584
585TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800586 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
587 SonameAfterDtNull<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800588}
589
590TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800591 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
592 SonameAfterDtNull<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800593}
594
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800595template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800596void ElfInterfaceTest::SonameSize() {
597 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
598
Christopher Ferrise69f4702017-10-19 16:08:58 -0700599 uint64_t load_bias = 0;
600 ASSERT_TRUE(elf->Init(&load_bias));
601 EXPECT_EQ(0U, load_bias);
602
Christopher Ferris3958f802017-02-01 15:44:40 -0800603 std::string name;
604 ASSERT_FALSE(elf->GetSoname(&name));
605}
606
607TEST_F(ElfInterfaceTest, elf32_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800608 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
609 SonameSize<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800610}
611
612TEST_F(ElfInterfaceTest, elf64_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800613 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
614 SonameSize<ElfInterface64>();
615}
616
617// Verify that there is no map from STRTAB in the dynamic section to a
618// STRTAB entry in the section headers.
619template <typename ElfInterfaceType>
620void ElfInterfaceTest::SonameMissingMap() {
621 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
622
623 uint64_t load_bias = 0;
624 ASSERT_TRUE(elf->Init(&load_bias));
625 EXPECT_EQ(0U, load_bias);
626
627 std::string name;
628 ASSERT_FALSE(elf->GetSoname(&name));
629}
630
631TEST_F(ElfInterfaceTest, elf32_soname_missing_map) {
632 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
633 SonameMissingMap<ElfInterface32>();
634}
635
636TEST_F(ElfInterfaceTest, elf64_soname_missing_map) {
637 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
638 SonameMissingMap<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800639}
Christopher Ferris61d40972017-06-12 19:14:20 -0700640
Christopher Ferris61d40972017-06-12 19:14:20 -0700641template <typename ElfType>
642void ElfInterfaceTest::InitHeadersEhFrameTest() {
643 ElfType elf(&memory_);
644
Christopher Ferrise69f4702017-10-19 16:08:58 -0700645 elf.FakeSetEhFrameOffset(0x10000);
646 elf.FakeSetEhFrameSize(0);
647 elf.FakeSetDebugFrameOffset(0);
648 elf.FakeSetDebugFrameSize(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700649
650 memory_.SetMemory(0x10000,
651 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
652 memory_.SetData32(0x10004, 0x500);
653 memory_.SetData32(0x10008, 250);
654
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700655 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700656
657 EXPECT_FALSE(elf.eh_frame() == nullptr);
658 EXPECT_TRUE(elf.debug_frame() == nullptr);
659}
660
661TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700662 InitHeadersEhFrameTest<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700663}
664
665TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700666 InitHeadersEhFrameTest<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700667}
668
669template <typename ElfType>
670void ElfInterfaceTest::InitHeadersDebugFrame() {
671 ElfType elf(&memory_);
672
Christopher Ferrise69f4702017-10-19 16:08:58 -0700673 elf.FakeSetEhFrameOffset(0);
674 elf.FakeSetEhFrameSize(0);
675 elf.FakeSetDebugFrameOffset(0x5000);
676 elf.FakeSetDebugFrameSize(0x200);
Christopher Ferris61d40972017-06-12 19:14:20 -0700677
678 memory_.SetData32(0x5000, 0xfc);
679 memory_.SetData32(0x5004, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -0700680 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
Christopher Ferris61d40972017-06-12 19:14:20 -0700681
682 memory_.SetData32(0x5100, 0xfc);
683 memory_.SetData32(0x5104, 0);
684 memory_.SetData32(0x5108, 0x1500);
685 memory_.SetData32(0x510c, 0x200);
686
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700687 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700688
689 EXPECT_TRUE(elf.eh_frame() == nullptr);
690 EXPECT_FALSE(elf.debug_frame() == nullptr);
691}
692
693TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700694 InitHeadersDebugFrame<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700695}
696
697TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700698 InitHeadersDebugFrame<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700699}
700
Christopher Ferris5acf0692018-08-01 13:10:46 -0700701template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
702void ElfInterfaceTest::InitProgramHeadersMalformed() {
703 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
704
705 Ehdr ehdr = {};
706 ehdr.e_phoff = 0x100;
707 ehdr.e_phnum = 3;
708 ehdr.e_phentsize = sizeof(Phdr);
709 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
710
711 uint64_t load_bias = 0;
712 ASSERT_TRUE(elf->Init(&load_bias));
713 EXPECT_EQ(0U, load_bias);
714}
715
716TEST_F(ElfInterfaceTest, init_program_headers_malformed32) {
717 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
718}
719
720TEST_F(ElfInterfaceTest, init_program_headers_malformed64) {
721 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
722}
723
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700724template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
725void ElfInterfaceTest::InitSectionHeadersMalformed() {
726 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
727
Christopher Ferrisf882a382018-06-22 16:48:02 -0700728 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700729 ehdr.e_shoff = 0x1000;
730 ehdr.e_shnum = 10;
731 ehdr.e_shentsize = sizeof(Shdr);
732 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
733
Christopher Ferrise69f4702017-10-19 16:08:58 -0700734 uint64_t load_bias = 0;
735 ASSERT_TRUE(elf->Init(&load_bias));
736 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700737}
738
739TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
740 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
741}
742
743TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
744 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
745}
746
Christopher Ferris5acf0692018-08-01 13:10:46 -0700747template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
748void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
749 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
750
751 uint64_t offset = 0x1000;
752
753 Ehdr ehdr = {};
754 ehdr.e_shoff = offset;
755 ehdr.e_shnum = 5;
756 ehdr.e_shentsize = sizeof(Shdr);
757 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
758
759 offset += ehdr.e_shentsize;
760
761 Shdr shdr = {};
762 shdr.sh_type = SHT_SYMTAB;
763 shdr.sh_link = 4;
764 shdr.sh_addr = 0x5000;
765 shdr.sh_offset = 0x5000;
766 shdr.sh_entsize = 0x100;
767 shdr.sh_size = shdr.sh_entsize * 10;
768 memory_.SetMemory(offset, &shdr, sizeof(shdr));
769 offset += ehdr.e_shentsize;
770
771 memset(&shdr, 0, sizeof(shdr));
772 shdr.sh_type = SHT_DYNSYM;
773 shdr.sh_link = 10;
774 shdr.sh_addr = 0x6000;
775 shdr.sh_offset = 0x6000;
776 shdr.sh_entsize = 0x100;
777 shdr.sh_size = shdr.sh_entsize * 10;
778 memory_.SetMemory(offset, &shdr, sizeof(shdr));
779 offset += ehdr.e_shentsize;
780
781 memset(&shdr, 0, sizeof(shdr));
782 shdr.sh_type = SHT_DYNSYM;
783 shdr.sh_link = 2;
784 shdr.sh_addr = 0x6000;
785 shdr.sh_offset = 0x6000;
786 shdr.sh_entsize = 0x100;
787 shdr.sh_size = shdr.sh_entsize * 10;
788 memory_.SetMemory(offset, &shdr, sizeof(shdr));
789 offset += ehdr.e_shentsize;
790
791 // The string data for the entries.
792 memset(&shdr, 0, sizeof(shdr));
793 shdr.sh_type = SHT_STRTAB;
794 shdr.sh_name = 0x20000;
795 shdr.sh_offset = 0xf000;
796 shdr.sh_size = 0x1000;
797 memory_.SetMemory(offset, &shdr, sizeof(shdr));
798 offset += ehdr.e_shentsize;
799
800 uint64_t load_bias = 0;
801 ASSERT_TRUE(elf->Init(&load_bias));
802 EXPECT_EQ(0U, load_bias);
803 EXPECT_EQ(0U, elf->debug_frame_offset());
804 EXPECT_EQ(0U, elf->debug_frame_size());
805 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
806 EXPECT_EQ(0U, elf->gnu_debugdata_size());
807
808 std::string name;
809 uint64_t name_offset;
810 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
811}
812
813TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata32) {
814 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
815}
816
817TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata64) {
818 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
819}
820
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700821template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
822void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
823 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
824
825 uint64_t offset = 0x1000;
826
Christopher Ferrisf882a382018-06-22 16:48:02 -0700827 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700828 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700829 ehdr.e_shnum = 5;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700830 ehdr.e_shentsize = entry_size;
831 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
832
833 offset += ehdr.e_shentsize;
834
Christopher Ferrisf882a382018-06-22 16:48:02 -0700835 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700836 shdr.sh_type = SHT_SYMTAB;
837 shdr.sh_link = 4;
838 shdr.sh_addr = 0x5000;
839 shdr.sh_offset = 0x5000;
840 shdr.sh_entsize = sizeof(Sym);
841 shdr.sh_size = shdr.sh_entsize * 10;
842 memory_.SetMemory(offset, &shdr, sizeof(shdr));
843 offset += ehdr.e_shentsize;
844
845 memset(&shdr, 0, sizeof(shdr));
846 shdr.sh_type = SHT_DYNSYM;
847 shdr.sh_link = 4;
848 shdr.sh_addr = 0x6000;
849 shdr.sh_offset = 0x6000;
850 shdr.sh_entsize = sizeof(Sym);
851 shdr.sh_size = shdr.sh_entsize * 10;
852 memory_.SetMemory(offset, &shdr, sizeof(shdr));
853 offset += ehdr.e_shentsize;
854
855 memset(&shdr, 0, sizeof(shdr));
856 shdr.sh_type = SHT_PROGBITS;
857 shdr.sh_name = 0xa000;
858 memory_.SetMemory(offset, &shdr, sizeof(shdr));
859 offset += ehdr.e_shentsize;
860
861 // The string data for the entries.
862 memset(&shdr, 0, sizeof(shdr));
863 shdr.sh_type = SHT_STRTAB;
864 shdr.sh_name = 0x20000;
865 shdr.sh_offset = 0xf000;
866 shdr.sh_size = 0x1000;
867 memory_.SetMemory(offset, &shdr, sizeof(shdr));
868 offset += ehdr.e_shentsize;
869
870 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
871 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
872
Christopher Ferrise69f4702017-10-19 16:08:58 -0700873 uint64_t load_bias = 0;
874 ASSERT_TRUE(elf->Init(&load_bias));
875 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700876 EXPECT_EQ(0U, elf->debug_frame_offset());
877 EXPECT_EQ(0U, elf->debug_frame_size());
878 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
879 EXPECT_EQ(0U, elf->gnu_debugdata_size());
880
881 // Look in the first symbol table.
882 std::string name;
883 uint64_t name_offset;
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700884 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700885 EXPECT_EQ("function_one", name);
886 EXPECT_EQ(16U, name_offset);
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700887 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700888 EXPECT_EQ("function_two", name);
889 EXPECT_EQ(32U, name_offset);
890}
891
892TEST_F(ElfInterfaceTest, init_section_headers32) {
893 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
894}
895
896TEST_F(ElfInterfaceTest, init_section_headers64) {
897 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
898}
899
900TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
901 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
902}
903
904TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
905 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
906}
907
908template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
909void ElfInterfaceTest::InitSectionHeadersOffsets() {
910 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
911
912 uint64_t offset = 0x2000;
913
Christopher Ferrisf882a382018-06-22 16:48:02 -0700914 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700915 ehdr.e_shoff = offset;
Florian Mayerda459e52018-11-23 16:56:17 +0000916 ehdr.e_shnum = 7;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700917 ehdr.e_shentsize = sizeof(Shdr);
918 ehdr.e_shstrndx = 2;
919 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
920
921 offset += ehdr.e_shentsize;
922
Christopher Ferrisf882a382018-06-22 16:48:02 -0700923 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700924 shdr.sh_type = SHT_PROGBITS;
925 shdr.sh_link = 2;
926 shdr.sh_name = 0x200;
927 shdr.sh_addr = 0x5000;
928 shdr.sh_offset = 0x5000;
929 shdr.sh_entsize = 0x100;
930 shdr.sh_size = 0x800;
931 memory_.SetMemory(offset, &shdr, sizeof(shdr));
932 offset += ehdr.e_shentsize;
933
934 // The string data for section header names.
935 memset(&shdr, 0, sizeof(shdr));
936 shdr.sh_type = SHT_STRTAB;
937 shdr.sh_name = 0x20000;
938 shdr.sh_offset = 0xf000;
939 shdr.sh_size = 0x1000;
940 memory_.SetMemory(offset, &shdr, sizeof(shdr));
941 offset += ehdr.e_shentsize;
942
943 memset(&shdr, 0, sizeof(shdr));
944 shdr.sh_type = SHT_PROGBITS;
945 shdr.sh_link = 2;
946 shdr.sh_name = 0x100;
947 shdr.sh_addr = 0x6000;
948 shdr.sh_offset = 0x6000;
949 shdr.sh_entsize = 0x100;
950 shdr.sh_size = 0x500;
951 memory_.SetMemory(offset, &shdr, sizeof(shdr));
952 offset += ehdr.e_shentsize;
953
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700954 memset(&shdr, 0, sizeof(shdr));
955 shdr.sh_type = SHT_PROGBITS;
956 shdr.sh_link = 2;
957 shdr.sh_name = 0x300;
958 shdr.sh_addr = 0x7000;
959 shdr.sh_offset = 0x7000;
960 shdr.sh_entsize = 0x100;
961 shdr.sh_size = 0x800;
962 memory_.SetMemory(offset, &shdr, sizeof(shdr));
963 offset += ehdr.e_shentsize;
964
965 memset(&shdr, 0, sizeof(shdr));
966 shdr.sh_type = SHT_PROGBITS;
967 shdr.sh_link = 2;
968 shdr.sh_name = 0x400;
969 shdr.sh_addr = 0x6000;
970 shdr.sh_offset = 0xa000;
971 shdr.sh_entsize = 0x100;
972 shdr.sh_size = 0xf00;
973 memory_.SetMemory(offset, &shdr, sizeof(shdr));
974 offset += ehdr.e_shentsize;
975
Florian Mayerda459e52018-11-23 16:56:17 +0000976 memset(&shdr, 0, sizeof(shdr));
977 shdr.sh_type = SHT_NOTE;
978 shdr.sh_name = 0x500;
979 shdr.sh_offset = 0xb000;
980 shdr.sh_size = 0xf00;
981 memory_.SetMemory(offset, &shdr, sizeof(shdr));
982 offset += ehdr.e_shentsize;
983
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700984 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
985 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700986 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
987 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
Florian Mayerda459e52018-11-23 16:56:17 +0000988 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700989
Christopher Ferrise69f4702017-10-19 16:08:58 -0700990 uint64_t load_bias = 0;
991 ASSERT_TRUE(elf->Init(&load_bias));
992 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700993 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
994 EXPECT_EQ(0x500U, elf->debug_frame_size());
995 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
996 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700997 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
998 EXPECT_EQ(0x800U, elf->eh_frame_size());
999 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
1000 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
Florian Mayerda459e52018-11-23 16:56:17 +00001001 EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
1002 EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001003}
1004
1005TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
1006 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1007}
1008
1009TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
1010 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1011}
Christopher Ferrisd226a512017-07-14 10:37:19 -07001012
Christopher Ferris150db122017-12-20 18:49:01 -08001013TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
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 = 0;
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(0U, load_bias);
1033 EXPECT_TRUE(elf->IsValidPc(0));
1034 EXPECT_TRUE(elf->IsValidPc(0x5000));
1035 EXPECT_TRUE(elf->IsValidPc(0xffff));
1036 EXPECT_FALSE(elf->IsValidPc(0x10000));
1037}
1038
1039TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1040 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1041
Christopher Ferrisf882a382018-06-22 16:48:02 -07001042 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001043 ehdr.e_phoff = 0x100;
1044 ehdr.e_phnum = 1;
1045 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1046 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1047
Christopher Ferrisf882a382018-06-22 16:48:02 -07001048 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001049 phdr.p_type = PT_LOAD;
1050 phdr.p_vaddr = 0x2000;
1051 phdr.p_memsz = 0x10000;
1052 phdr.p_flags = PF_R | PF_X;
1053 phdr.p_align = 0x1000;
1054 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1055
1056 uint64_t load_bias = 0;
1057 ASSERT_TRUE(elf->Init(&load_bias));
1058 EXPECT_EQ(0x2000U, load_bias);
1059 EXPECT_FALSE(elf->IsValidPc(0));
1060 EXPECT_FALSE(elf->IsValidPc(0x1000));
1061 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1062 EXPECT_TRUE(elf->IsValidPc(0x2000));
1063 EXPECT_TRUE(elf->IsValidPc(0x5000));
1064 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1065 EXPECT_FALSE(elf->IsValidPc(0x12000));
1066}
1067
1068TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1069 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1070
1071 uint64_t sh_offset = 0x100;
1072
Christopher Ferrisf882a382018-06-22 16:48:02 -07001073 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001074 ehdr.e_shstrndx = 1;
1075 ehdr.e_shoff = sh_offset;
1076 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1077 ehdr.e_shnum = 3;
1078 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1079
Christopher Ferrisf882a382018-06-22 16:48:02 -07001080 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001081 shdr.sh_type = SHT_NULL;
1082 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1083
1084 sh_offset += sizeof(shdr);
1085 memset(&shdr, 0, sizeof(shdr));
1086 shdr.sh_type = SHT_STRTAB;
1087 shdr.sh_name = 1;
1088 shdr.sh_offset = 0x500;
1089 shdr.sh_size = 0x100;
1090 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1091 memory_.SetMemory(0x500, ".debug_frame");
1092
1093 sh_offset += sizeof(shdr);
1094 memset(&shdr, 0, sizeof(shdr));
1095 shdr.sh_type = SHT_PROGBITS;
1096 shdr.sh_name = 0;
1097 shdr.sh_addr = 0x600;
1098 shdr.sh_offset = 0x600;
1099 shdr.sh_size = 0x200;
1100 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1101
1102 // CIE 32.
1103 memory_.SetData32(0x600, 0xfc);
1104 memory_.SetData32(0x604, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001105 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001106
1107 // FDE 32.
1108 memory_.SetData32(0x700, 0xfc);
1109 memory_.SetData32(0x704, 0);
1110 memory_.SetData32(0x708, 0x2100);
1111 memory_.SetData32(0x70c, 0x200);
1112
1113 uint64_t load_bias = 0;
1114 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001115 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001116 EXPECT_EQ(0U, load_bias);
1117 EXPECT_FALSE(elf->IsValidPc(0));
1118 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1119 EXPECT_TRUE(elf->IsValidPc(0x2100));
1120 EXPECT_TRUE(elf->IsValidPc(0x2200));
1121 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1122 EXPECT_FALSE(elf->IsValidPc(0x2300));
1123}
1124
1125TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1126 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1127
1128 uint64_t sh_offset = 0x100;
1129
Christopher Ferrisf882a382018-06-22 16:48:02 -07001130 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001131 ehdr.e_shstrndx = 1;
1132 ehdr.e_shoff = sh_offset;
1133 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1134 ehdr.e_shnum = 3;
1135 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1136
Christopher Ferrisf882a382018-06-22 16:48:02 -07001137 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001138 shdr.sh_type = SHT_NULL;
1139 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1140
1141 sh_offset += sizeof(shdr);
1142 memset(&shdr, 0, sizeof(shdr));
1143 shdr.sh_type = SHT_STRTAB;
1144 shdr.sh_name = 1;
1145 shdr.sh_offset = 0x500;
1146 shdr.sh_size = 0x100;
1147 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1148 memory_.SetMemory(0x500, ".eh_frame");
1149
1150 sh_offset += sizeof(shdr);
1151 memset(&shdr, 0, sizeof(shdr));
1152 shdr.sh_type = SHT_PROGBITS;
1153 shdr.sh_name = 0;
1154 shdr.sh_addr = 0x600;
1155 shdr.sh_offset = 0x600;
1156 shdr.sh_size = 0x200;
1157 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1158
1159 // CIE 32.
1160 memory_.SetData32(0x600, 0xfc);
1161 memory_.SetData32(0x604, 0);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001162 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001163
1164 // FDE 32.
1165 memory_.SetData32(0x700, 0xfc);
1166 memory_.SetData32(0x704, 0x104);
1167 memory_.SetData32(0x708, 0x20f8);
1168 memory_.SetData32(0x70c, 0x200);
1169
1170 uint64_t load_bias = 0;
1171 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001172 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001173 EXPECT_EQ(0U, load_bias);
1174 EXPECT_FALSE(elf->IsValidPc(0));
1175 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1176 EXPECT_TRUE(elf->IsValidPc(0x2800));
1177 EXPECT_TRUE(elf->IsValidPc(0x2900));
1178 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1179 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1180}
1181
Florian Mayerda459e52018-11-23 16:56:17 +00001182template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1183void ElfInterfaceTest::BuildID() {
1184 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1185
1186 uint64_t offset = 0x2000;
1187
1188 Ehdr ehdr = {};
1189 ehdr.e_shoff = offset;
1190 ehdr.e_shnum = 3;
1191 ehdr.e_shentsize = sizeof(Shdr);
1192 ehdr.e_shstrndx = 2;
1193 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1194
1195 offset += ehdr.e_shentsize;
1196
1197 char note_section[128];
1198 Nhdr note_header = {};
1199 note_header.n_namesz = 4; // "GNU"
1200 note_header.n_descsz = 8; // "BUILDID"
1201 note_header.n_type = NT_GNU_BUILD_ID;
1202 memcpy(&note_section, &note_header, sizeof(note_header));
1203 size_t note_offset = sizeof(note_header);
1204 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1205 note_offset += sizeof("GNU");
1206 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1207 note_offset += sizeof("BUILDID");
1208
1209 Shdr shdr = {};
1210 shdr.sh_type = SHT_NOTE;
1211 shdr.sh_name = 0x500;
1212 shdr.sh_offset = 0xb000;
1213 shdr.sh_size = sizeof(note_section);
1214 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1215 offset += ehdr.e_shentsize;
1216
1217 // The string data for section header names.
1218 memset(&shdr, 0, sizeof(shdr));
1219 shdr.sh_type = SHT_STRTAB;
1220 shdr.sh_name = 0x20000;
1221 shdr.sh_offset = 0xf000;
1222 shdr.sh_size = 0x1000;
1223 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1224 offset += ehdr.e_shentsize;
1225
1226 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1227 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1228
1229 uint64_t load_bias = 0;
1230 ASSERT_TRUE(elf->Init(&load_bias));
1231 std::string build_id;
1232 ASSERT_TRUE(elf->GetBuildID(&build_id));
1233 EXPECT_STREQ(build_id.c_str(), "BUILDID");
1234}
1235
1236template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1237void ElfInterfaceTest::BuildIDTwoNotes() {
1238 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1239
1240 uint64_t offset = 0x2000;
1241
1242 Ehdr ehdr = {};
1243 ehdr.e_shoff = offset;
1244 ehdr.e_shnum = 3;
1245 ehdr.e_shentsize = sizeof(Shdr);
1246 ehdr.e_shstrndx = 2;
1247 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1248
1249 offset += ehdr.e_shentsize;
1250
1251 char note_section[128];
1252 Nhdr note_header = {};
1253 note_header.n_namesz = 8; // "WRONG" aligned to 4
1254 note_header.n_descsz = 8; // "BUILDID"
1255 note_header.n_type = NT_GNU_BUILD_ID;
1256 memcpy(&note_section, &note_header, sizeof(note_header));
1257 size_t note_offset = sizeof(note_header);
1258 memcpy(&note_section[note_offset], "WRONG", sizeof("WRONG"));
1259 note_offset += 8;
1260 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1261 note_offset += sizeof("BUILDID");
1262
1263 note_header.n_namesz = 4; // "GNU"
1264 note_header.n_descsz = 8; // "BUILDID"
1265 note_header.n_type = NT_GNU_BUILD_ID;
1266 memcpy(&note_section[note_offset], &note_header, sizeof(note_header));
1267 note_offset += sizeof(note_header);
1268 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1269 note_offset += sizeof("GNU");
1270 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1271 note_offset += sizeof("BUILDID");
1272
1273 Shdr shdr = {};
1274 shdr.sh_type = SHT_NOTE;
1275 shdr.sh_name = 0x500;
1276 shdr.sh_offset = 0xb000;
1277 shdr.sh_size = sizeof(note_section);
1278 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1279 offset += ehdr.e_shentsize;
1280
1281 // The string data for section header names.
1282 memset(&shdr, 0, sizeof(shdr));
1283 shdr.sh_type = SHT_STRTAB;
1284 shdr.sh_name = 0x20000;
1285 shdr.sh_offset = 0xf000;
1286 shdr.sh_size = 0x1000;
1287 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1288 offset += ehdr.e_shentsize;
1289
1290 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1291 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1292
1293 uint64_t load_bias = 0;
1294 ASSERT_TRUE(elf->Init(&load_bias));
1295 std::string build_id;
1296 ASSERT_TRUE(elf->GetBuildID(&build_id));
1297 EXPECT_STREQ(build_id.c_str(), "BUILDID");
1298}
1299
1300template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1301void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1302 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1303
1304 uint64_t offset = 0x2000;
1305
1306 Ehdr ehdr = {};
1307 ehdr.e_shoff = offset;
1308 ehdr.e_shnum = 3;
1309 ehdr.e_shentsize = sizeof(Shdr);
1310 ehdr.e_shstrndx = 2;
1311 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1312
1313 offset += ehdr.e_shentsize;
1314
1315 char note_section[128];
1316 Nhdr note_header = {};
1317 note_header.n_namesz = 4; // "GNU"
1318 note_header.n_descsz = 8; // "BUILDID"
1319 note_header.n_type = NT_GNU_BUILD_ID;
1320 memcpy(&note_section, &note_header, sizeof(note_header));
1321 size_t note_offset = sizeof(note_header);
1322 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1323 note_offset += sizeof("GNU");
1324 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1325 note_offset += sizeof("BUILDID");
1326
1327 Shdr shdr = {};
1328 shdr.sh_type = SHT_NOTE;
1329 shdr.sh_name = 0x500;
1330 shdr.sh_offset = 0xb000;
1331 shdr.sh_size = sizeof(note_header) + 1;
1332 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1333 offset += ehdr.e_shentsize;
1334
1335 // The string data for section header names.
1336 memset(&shdr, 0, sizeof(shdr));
1337 shdr.sh_type = SHT_STRTAB;
1338 shdr.sh_name = 0x20000;
1339 shdr.sh_offset = 0xf000;
1340 shdr.sh_size = 0x1000;
1341 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1342 offset += ehdr.e_shentsize;
1343
1344 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1345 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1346
1347 uint64_t load_bias = 0;
1348 ASSERT_TRUE(elf->Init(&load_bias));
1349 std::string build_id;
1350 ASSERT_FALSE(elf->GetBuildID(&build_id));
1351}
1352
1353template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1354void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1355 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1356
1357 uint64_t offset = 0x2000;
1358
1359 Ehdr ehdr = {};
1360 ehdr.e_shoff = offset;
1361 ehdr.e_shnum = 3;
1362 ehdr.e_shentsize = sizeof(Shdr);
1363 ehdr.e_shstrndx = 2;
1364 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1365
1366 offset += ehdr.e_shentsize;
1367
1368 char note_section[128];
1369 Nhdr note_header = {};
1370 note_header.n_namesz = 4; // "GNU"
1371 note_header.n_descsz = 8; // "BUILDID"
1372 note_header.n_type = NT_GNU_BUILD_ID;
1373 memcpy(&note_section, &note_header, sizeof(note_header));
1374 size_t note_offset = sizeof(note_header);
1375 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1376 note_offset += sizeof("GNU");
1377 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1378 note_offset += sizeof("BUILDID");
1379
1380 Shdr shdr = {};
1381 shdr.sh_type = SHT_NOTE;
1382 shdr.sh_name = 0x500;
1383 shdr.sh_offset = 0xb000;
1384 shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1385 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1386 offset += ehdr.e_shentsize;
1387
1388 // The string data for section header names.
1389 memset(&shdr, 0, sizeof(shdr));
1390 shdr.sh_type = SHT_STRTAB;
1391 shdr.sh_name = 0x20000;
1392 shdr.sh_offset = 0xf000;
1393 shdr.sh_size = 0x1000;
1394 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1395 offset += ehdr.e_shentsize;
1396
1397 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1398 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1399
1400 uint64_t load_bias = 0;
1401 ASSERT_TRUE(elf->Init(&load_bias));
1402 std::string build_id;
1403 ASSERT_FALSE(elf->GetBuildID(&build_id));
1404}
1405
1406template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1407void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1408 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1409
1410 uint64_t offset = 0x2000;
1411
1412 Ehdr ehdr = {};
1413 ehdr.e_shoff = offset;
1414 ehdr.e_shnum = 3;
1415 ehdr.e_shentsize = sizeof(Shdr);
1416 ehdr.e_shstrndx = 2;
1417 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1418
1419 offset += ehdr.e_shentsize;
1420
1421 char note_section[128];
1422 Nhdr note_header = {};
1423 note_header.n_namesz = 4; // "GNU"
1424 note_header.n_descsz = 8; // "BUILDID"
1425 note_header.n_type = NT_GNU_BUILD_ID;
1426 memcpy(&note_section, &note_header, sizeof(note_header));
1427 size_t note_offset = sizeof(note_header);
1428 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1429 note_offset += sizeof("GNU");
1430 memcpy(&note_section[note_offset], "BUILDID", sizeof("BUILDID"));
1431 note_offset += sizeof("BUILDID");
1432
1433 Shdr shdr = {};
1434 shdr.sh_type = SHT_NOTE;
1435 shdr.sh_name = 0x500;
1436 shdr.sh_offset = 0xb000;
1437 shdr.sh_size = sizeof(note_header) - 1;
1438 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1439 offset += ehdr.e_shentsize;
1440
1441 // The string data for section header names.
1442 memset(&shdr, 0, sizeof(shdr));
1443 shdr.sh_type = SHT_STRTAB;
1444 shdr.sh_name = 0x20000;
1445 shdr.sh_offset = 0xf000;
1446 shdr.sh_size = 0x1000;
1447 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1448 offset += ehdr.e_shentsize;
1449
1450 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1451 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1452
1453 uint64_t load_bias = 0;
1454 ASSERT_TRUE(elf->Init(&load_bias));
1455 std::string build_id;
1456 ASSERT_FALSE(elf->GetBuildID(&build_id));
1457}
1458
1459TEST_F(ElfInterfaceTest, build_id32) {
1460 BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1461}
1462
1463TEST_F(ElfInterfaceTest, build_id64) {
1464 BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1465}
1466
1467TEST_F(ElfInterfaceTest, build_id_two_notes32) {
1468 BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1469}
1470
1471TEST_F(ElfInterfaceTest, build_id_two_notes64) {
1472 BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1473}
1474
1475TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name32) {
1476 BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1477}
1478
1479TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name64) {
1480 BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1481}
1482
1483TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc32) {
1484 BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1485}
1486
1487TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc64) {
1488 BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1489}
1490
1491TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header32) {
1492 BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1493}
1494
1495TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header64) {
1496 BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1497}
1498
Christopher Ferrisd226a512017-07-14 10:37:19 -07001499} // namespace unwindstack