blob: cdc927aba1524b75d40588b30e199bb564820137 [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 Ferris02a6c442019-03-11 14:43:33 -0700558 ASSERT_EQ("fake_soname.so", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800559}
560
561TEST_F(ElfInterfaceTest, elf32_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800562 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
563 Soname<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800564}
565
566TEST_F(ElfInterfaceTest, elf64_soname) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800567 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
568 Soname<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800569}
570
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800571template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800572void ElfInterfaceTest::SonameAfterDtNull() {
573 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
574
Christopher Ferrise69f4702017-10-19 16:08:58 -0700575 uint64_t load_bias = 0;
576 ASSERT_TRUE(elf->Init(&load_bias));
577 EXPECT_EQ(0U, load_bias);
578
Christopher Ferris02a6c442019-03-11 14:43:33 -0700579 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800580}
581
582TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800583 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
584 SonameAfterDtNull<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800585}
586
587TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800588 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
589 SonameAfterDtNull<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800590}
591
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800592template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800593void ElfInterfaceTest::SonameSize() {
594 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
595
Christopher Ferrise69f4702017-10-19 16:08:58 -0700596 uint64_t load_bias = 0;
597 ASSERT_TRUE(elf->Init(&load_bias));
598 EXPECT_EQ(0U, load_bias);
599
Christopher Ferris02a6c442019-03-11 14:43:33 -0700600 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800601}
602
603TEST_F(ElfInterfaceTest, elf32_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800604 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
605 SonameSize<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800606}
607
608TEST_F(ElfInterfaceTest, elf64_soname_size) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800609 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
610 SonameSize<ElfInterface64>();
611}
612
613// Verify that there is no map from STRTAB in the dynamic section to a
614// STRTAB entry in the section headers.
615template <typename ElfInterfaceType>
616void ElfInterfaceTest::SonameMissingMap() {
617 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
618
619 uint64_t load_bias = 0;
620 ASSERT_TRUE(elf->Init(&load_bias));
621 EXPECT_EQ(0U, load_bias);
622
Christopher Ferris02a6c442019-03-11 14:43:33 -0700623 ASSERT_EQ("", elf->GetSoname());
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800624}
625
626TEST_F(ElfInterfaceTest, elf32_soname_missing_map) {
627 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
628 SonameMissingMap<ElfInterface32>();
629}
630
631TEST_F(ElfInterfaceTest, elf64_soname_missing_map) {
632 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
633 SonameMissingMap<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800634}
Christopher Ferris61d40972017-06-12 19:14:20 -0700635
Christopher Ferris61d40972017-06-12 19:14:20 -0700636template <typename ElfType>
637void ElfInterfaceTest::InitHeadersEhFrameTest() {
638 ElfType elf(&memory_);
639
Christopher Ferrise69f4702017-10-19 16:08:58 -0700640 elf.FakeSetEhFrameOffset(0x10000);
641 elf.FakeSetEhFrameSize(0);
642 elf.FakeSetDebugFrameOffset(0);
643 elf.FakeSetDebugFrameSize(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700644
645 memory_.SetMemory(0x10000,
646 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
647 memory_.SetData32(0x10004, 0x500);
648 memory_.SetData32(0x10008, 250);
649
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700650 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700651
652 EXPECT_FALSE(elf.eh_frame() == nullptr);
653 EXPECT_TRUE(elf.debug_frame() == nullptr);
654}
655
656TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700657 InitHeadersEhFrameTest<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700658}
659
660TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700661 InitHeadersEhFrameTest<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700662}
663
664template <typename ElfType>
665void ElfInterfaceTest::InitHeadersDebugFrame() {
666 ElfType elf(&memory_);
667
Christopher Ferrise69f4702017-10-19 16:08:58 -0700668 elf.FakeSetEhFrameOffset(0);
669 elf.FakeSetEhFrameSize(0);
670 elf.FakeSetDebugFrameOffset(0x5000);
671 elf.FakeSetDebugFrameSize(0x200);
Christopher Ferris61d40972017-06-12 19:14:20 -0700672
673 memory_.SetData32(0x5000, 0xfc);
674 memory_.SetData32(0x5004, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -0700675 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
Christopher Ferris61d40972017-06-12 19:14:20 -0700676
677 memory_.SetData32(0x5100, 0xfc);
678 memory_.SetData32(0x5104, 0);
679 memory_.SetData32(0x5108, 0x1500);
680 memory_.SetData32(0x510c, 0x200);
681
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700682 elf.InitHeaders(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700683
684 EXPECT_TRUE(elf.eh_frame() == nullptr);
685 EXPECT_FALSE(elf.debug_frame() == nullptr);
686}
687
688TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700689 InitHeadersDebugFrame<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700690}
691
692TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700693 InitHeadersDebugFrame<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700694}
695
Christopher Ferris5acf0692018-08-01 13:10:46 -0700696template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
697void ElfInterfaceTest::InitProgramHeadersMalformed() {
698 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
699
700 Ehdr ehdr = {};
701 ehdr.e_phoff = 0x100;
702 ehdr.e_phnum = 3;
703 ehdr.e_phentsize = sizeof(Phdr);
704 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
705
706 uint64_t load_bias = 0;
707 ASSERT_TRUE(elf->Init(&load_bias));
708 EXPECT_EQ(0U, load_bias);
709}
710
711TEST_F(ElfInterfaceTest, init_program_headers_malformed32) {
712 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
713}
714
715TEST_F(ElfInterfaceTest, init_program_headers_malformed64) {
716 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
717}
718
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700719template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
720void ElfInterfaceTest::InitSectionHeadersMalformed() {
721 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
722
Christopher Ferrisf882a382018-06-22 16:48:02 -0700723 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700724 ehdr.e_shoff = 0x1000;
725 ehdr.e_shnum = 10;
726 ehdr.e_shentsize = sizeof(Shdr);
727 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
728
Christopher Ferrise69f4702017-10-19 16:08:58 -0700729 uint64_t load_bias = 0;
730 ASSERT_TRUE(elf->Init(&load_bias));
731 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700732}
733
734TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
735 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
736}
737
738TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
739 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
740}
741
Christopher Ferris5acf0692018-08-01 13:10:46 -0700742template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
743void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
744 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
745
746 uint64_t offset = 0x1000;
747
748 Ehdr ehdr = {};
749 ehdr.e_shoff = offset;
750 ehdr.e_shnum = 5;
751 ehdr.e_shentsize = sizeof(Shdr);
752 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
753
754 offset += ehdr.e_shentsize;
755
756 Shdr shdr = {};
757 shdr.sh_type = SHT_SYMTAB;
758 shdr.sh_link = 4;
759 shdr.sh_addr = 0x5000;
760 shdr.sh_offset = 0x5000;
761 shdr.sh_entsize = 0x100;
762 shdr.sh_size = shdr.sh_entsize * 10;
763 memory_.SetMemory(offset, &shdr, sizeof(shdr));
764 offset += ehdr.e_shentsize;
765
766 memset(&shdr, 0, sizeof(shdr));
767 shdr.sh_type = SHT_DYNSYM;
768 shdr.sh_link = 10;
769 shdr.sh_addr = 0x6000;
770 shdr.sh_offset = 0x6000;
771 shdr.sh_entsize = 0x100;
772 shdr.sh_size = shdr.sh_entsize * 10;
773 memory_.SetMemory(offset, &shdr, sizeof(shdr));
774 offset += ehdr.e_shentsize;
775
776 memset(&shdr, 0, sizeof(shdr));
777 shdr.sh_type = SHT_DYNSYM;
778 shdr.sh_link = 2;
779 shdr.sh_addr = 0x6000;
780 shdr.sh_offset = 0x6000;
781 shdr.sh_entsize = 0x100;
782 shdr.sh_size = shdr.sh_entsize * 10;
783 memory_.SetMemory(offset, &shdr, sizeof(shdr));
784 offset += ehdr.e_shentsize;
785
786 // The string data for the entries.
787 memset(&shdr, 0, sizeof(shdr));
788 shdr.sh_type = SHT_STRTAB;
789 shdr.sh_name = 0x20000;
790 shdr.sh_offset = 0xf000;
791 shdr.sh_size = 0x1000;
792 memory_.SetMemory(offset, &shdr, sizeof(shdr));
793 offset += ehdr.e_shentsize;
794
795 uint64_t load_bias = 0;
796 ASSERT_TRUE(elf->Init(&load_bias));
797 EXPECT_EQ(0U, load_bias);
798 EXPECT_EQ(0U, elf->debug_frame_offset());
799 EXPECT_EQ(0U, elf->debug_frame_size());
800 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
801 EXPECT_EQ(0U, elf->gnu_debugdata_size());
802
803 std::string name;
804 uint64_t name_offset;
805 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
806}
807
808TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata32) {
809 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
810}
811
812TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata64) {
813 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
814}
815
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700816template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
817void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
818 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
819
820 uint64_t offset = 0x1000;
821
Christopher Ferrisf882a382018-06-22 16:48:02 -0700822 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700823 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700824 ehdr.e_shnum = 5;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700825 ehdr.e_shentsize = entry_size;
826 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
827
828 offset += ehdr.e_shentsize;
829
Christopher Ferrisf882a382018-06-22 16:48:02 -0700830 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700831 shdr.sh_type = SHT_SYMTAB;
832 shdr.sh_link = 4;
833 shdr.sh_addr = 0x5000;
834 shdr.sh_offset = 0x5000;
835 shdr.sh_entsize = sizeof(Sym);
836 shdr.sh_size = shdr.sh_entsize * 10;
837 memory_.SetMemory(offset, &shdr, sizeof(shdr));
838 offset += ehdr.e_shentsize;
839
840 memset(&shdr, 0, sizeof(shdr));
841 shdr.sh_type = SHT_DYNSYM;
842 shdr.sh_link = 4;
843 shdr.sh_addr = 0x6000;
844 shdr.sh_offset = 0x6000;
845 shdr.sh_entsize = sizeof(Sym);
846 shdr.sh_size = shdr.sh_entsize * 10;
847 memory_.SetMemory(offset, &shdr, sizeof(shdr));
848 offset += ehdr.e_shentsize;
849
850 memset(&shdr, 0, sizeof(shdr));
851 shdr.sh_type = SHT_PROGBITS;
852 shdr.sh_name = 0xa000;
853 memory_.SetMemory(offset, &shdr, sizeof(shdr));
854 offset += ehdr.e_shentsize;
855
856 // The string data for the entries.
857 memset(&shdr, 0, sizeof(shdr));
858 shdr.sh_type = SHT_STRTAB;
859 shdr.sh_name = 0x20000;
860 shdr.sh_offset = 0xf000;
861 shdr.sh_size = 0x1000;
862 memory_.SetMemory(offset, &shdr, sizeof(shdr));
863 offset += ehdr.e_shentsize;
864
865 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
866 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
867
Christopher Ferrise69f4702017-10-19 16:08:58 -0700868 uint64_t load_bias = 0;
869 ASSERT_TRUE(elf->Init(&load_bias));
870 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700871 EXPECT_EQ(0U, elf->debug_frame_offset());
872 EXPECT_EQ(0U, elf->debug_frame_size());
873 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
874 EXPECT_EQ(0U, elf->gnu_debugdata_size());
875
876 // Look in the first symbol table.
877 std::string name;
878 uint64_t name_offset;
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700879 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700880 EXPECT_EQ("function_one", name);
881 EXPECT_EQ(16U, name_offset);
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700882 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700883 EXPECT_EQ("function_two", name);
884 EXPECT_EQ(32U, name_offset);
885}
886
887TEST_F(ElfInterfaceTest, init_section_headers32) {
888 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
889}
890
891TEST_F(ElfInterfaceTest, init_section_headers64) {
892 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
893}
894
895TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
896 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
897}
898
899TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
900 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
901}
902
903template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
904void ElfInterfaceTest::InitSectionHeadersOffsets() {
905 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
906
907 uint64_t offset = 0x2000;
908
Christopher Ferrisf882a382018-06-22 16:48:02 -0700909 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700910 ehdr.e_shoff = offset;
Florian Mayerda459e52018-11-23 16:56:17 +0000911 ehdr.e_shnum = 7;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700912 ehdr.e_shentsize = sizeof(Shdr);
913 ehdr.e_shstrndx = 2;
914 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
915
916 offset += ehdr.e_shentsize;
917
Christopher Ferrisf882a382018-06-22 16:48:02 -0700918 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700919 shdr.sh_type = SHT_PROGBITS;
920 shdr.sh_link = 2;
921 shdr.sh_name = 0x200;
922 shdr.sh_addr = 0x5000;
923 shdr.sh_offset = 0x5000;
924 shdr.sh_entsize = 0x100;
925 shdr.sh_size = 0x800;
926 memory_.SetMemory(offset, &shdr, sizeof(shdr));
927 offset += ehdr.e_shentsize;
928
929 // The string data for section header names.
930 memset(&shdr, 0, sizeof(shdr));
931 shdr.sh_type = SHT_STRTAB;
932 shdr.sh_name = 0x20000;
933 shdr.sh_offset = 0xf000;
934 shdr.sh_size = 0x1000;
935 memory_.SetMemory(offset, &shdr, sizeof(shdr));
936 offset += ehdr.e_shentsize;
937
938 memset(&shdr, 0, sizeof(shdr));
939 shdr.sh_type = SHT_PROGBITS;
940 shdr.sh_link = 2;
941 shdr.sh_name = 0x100;
942 shdr.sh_addr = 0x6000;
943 shdr.sh_offset = 0x6000;
944 shdr.sh_entsize = 0x100;
945 shdr.sh_size = 0x500;
946 memory_.SetMemory(offset, &shdr, sizeof(shdr));
947 offset += ehdr.e_shentsize;
948
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700949 memset(&shdr, 0, sizeof(shdr));
950 shdr.sh_type = SHT_PROGBITS;
951 shdr.sh_link = 2;
952 shdr.sh_name = 0x300;
953 shdr.sh_addr = 0x7000;
954 shdr.sh_offset = 0x7000;
955 shdr.sh_entsize = 0x100;
956 shdr.sh_size = 0x800;
957 memory_.SetMemory(offset, &shdr, sizeof(shdr));
958 offset += ehdr.e_shentsize;
959
960 memset(&shdr, 0, sizeof(shdr));
961 shdr.sh_type = SHT_PROGBITS;
962 shdr.sh_link = 2;
963 shdr.sh_name = 0x400;
964 shdr.sh_addr = 0x6000;
965 shdr.sh_offset = 0xa000;
966 shdr.sh_entsize = 0x100;
967 shdr.sh_size = 0xf00;
968 memory_.SetMemory(offset, &shdr, sizeof(shdr));
969 offset += ehdr.e_shentsize;
970
Florian Mayerda459e52018-11-23 16:56:17 +0000971 memset(&shdr, 0, sizeof(shdr));
972 shdr.sh_type = SHT_NOTE;
973 shdr.sh_name = 0x500;
974 shdr.sh_offset = 0xb000;
975 shdr.sh_size = 0xf00;
976 memory_.SetMemory(offset, &shdr, sizeof(shdr));
977 offset += ehdr.e_shentsize;
978
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700979 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
980 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700981 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
982 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
Florian Mayerda459e52018-11-23 16:56:17 +0000983 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700984
Christopher Ferrise69f4702017-10-19 16:08:58 -0700985 uint64_t load_bias = 0;
986 ASSERT_TRUE(elf->Init(&load_bias));
987 EXPECT_EQ(0U, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700988 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
989 EXPECT_EQ(0x500U, elf->debug_frame_size());
990 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
991 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700992 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
993 EXPECT_EQ(0x800U, elf->eh_frame_size());
994 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
995 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
Florian Mayerda459e52018-11-23 16:56:17 +0000996 EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
997 EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700998}
999
1000TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
1001 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1002}
1003
1004TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
1005 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1006}
Christopher Ferrisd226a512017-07-14 10:37:19 -07001007
Christopher Ferris150db122017-12-20 18:49:01 -08001008TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
1009 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1010
Christopher Ferrisf882a382018-06-22 16:48:02 -07001011 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001012 ehdr.e_phoff = 0x100;
1013 ehdr.e_phnum = 1;
1014 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1015 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1016
Christopher Ferrisf882a382018-06-22 16:48:02 -07001017 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001018 phdr.p_type = PT_LOAD;
1019 phdr.p_vaddr = 0;
1020 phdr.p_memsz = 0x10000;
1021 phdr.p_flags = PF_R | PF_X;
1022 phdr.p_align = 0x1000;
1023 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1024
1025 uint64_t load_bias = 0;
1026 ASSERT_TRUE(elf->Init(&load_bias));
1027 EXPECT_EQ(0U, load_bias);
1028 EXPECT_TRUE(elf->IsValidPc(0));
1029 EXPECT_TRUE(elf->IsValidPc(0x5000));
1030 EXPECT_TRUE(elf->IsValidPc(0xffff));
1031 EXPECT_FALSE(elf->IsValidPc(0x10000));
1032}
1033
1034TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1035 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1036
Christopher Ferrisf882a382018-06-22 16:48:02 -07001037 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001038 ehdr.e_phoff = 0x100;
1039 ehdr.e_phnum = 1;
1040 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1041 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1042
Christopher Ferrisf882a382018-06-22 16:48:02 -07001043 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001044 phdr.p_type = PT_LOAD;
1045 phdr.p_vaddr = 0x2000;
1046 phdr.p_memsz = 0x10000;
1047 phdr.p_flags = PF_R | PF_X;
1048 phdr.p_align = 0x1000;
1049 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1050
1051 uint64_t load_bias = 0;
1052 ASSERT_TRUE(elf->Init(&load_bias));
1053 EXPECT_EQ(0x2000U, load_bias);
1054 EXPECT_FALSE(elf->IsValidPc(0));
1055 EXPECT_FALSE(elf->IsValidPc(0x1000));
1056 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1057 EXPECT_TRUE(elf->IsValidPc(0x2000));
1058 EXPECT_TRUE(elf->IsValidPc(0x5000));
1059 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1060 EXPECT_FALSE(elf->IsValidPc(0x12000));
1061}
1062
1063TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1064 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1065
1066 uint64_t sh_offset = 0x100;
1067
Christopher Ferrisf882a382018-06-22 16:48:02 -07001068 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001069 ehdr.e_shstrndx = 1;
1070 ehdr.e_shoff = sh_offset;
1071 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1072 ehdr.e_shnum = 3;
1073 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1074
Christopher Ferrisf882a382018-06-22 16:48:02 -07001075 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001076 shdr.sh_type = SHT_NULL;
1077 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1078
1079 sh_offset += sizeof(shdr);
1080 memset(&shdr, 0, sizeof(shdr));
1081 shdr.sh_type = SHT_STRTAB;
1082 shdr.sh_name = 1;
1083 shdr.sh_offset = 0x500;
1084 shdr.sh_size = 0x100;
1085 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1086 memory_.SetMemory(0x500, ".debug_frame");
1087
1088 sh_offset += sizeof(shdr);
1089 memset(&shdr, 0, sizeof(shdr));
1090 shdr.sh_type = SHT_PROGBITS;
1091 shdr.sh_name = 0;
1092 shdr.sh_addr = 0x600;
1093 shdr.sh_offset = 0x600;
1094 shdr.sh_size = 0x200;
1095 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1096
1097 // CIE 32.
1098 memory_.SetData32(0x600, 0xfc);
1099 memory_.SetData32(0x604, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001100 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001101
1102 // FDE 32.
1103 memory_.SetData32(0x700, 0xfc);
1104 memory_.SetData32(0x704, 0);
1105 memory_.SetData32(0x708, 0x2100);
1106 memory_.SetData32(0x70c, 0x200);
1107
1108 uint64_t load_bias = 0;
1109 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001110 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001111 EXPECT_EQ(0U, load_bias);
1112 EXPECT_FALSE(elf->IsValidPc(0));
1113 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1114 EXPECT_TRUE(elf->IsValidPc(0x2100));
1115 EXPECT_TRUE(elf->IsValidPc(0x2200));
1116 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1117 EXPECT_FALSE(elf->IsValidPc(0x2300));
1118}
1119
1120TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1121 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1122
1123 uint64_t sh_offset = 0x100;
1124
Christopher Ferrisf882a382018-06-22 16:48:02 -07001125 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001126 ehdr.e_shstrndx = 1;
1127 ehdr.e_shoff = sh_offset;
1128 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1129 ehdr.e_shnum = 3;
1130 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1131
Christopher Ferrisf882a382018-06-22 16:48:02 -07001132 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001133 shdr.sh_type = SHT_NULL;
1134 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1135
1136 sh_offset += sizeof(shdr);
1137 memset(&shdr, 0, sizeof(shdr));
1138 shdr.sh_type = SHT_STRTAB;
1139 shdr.sh_name = 1;
1140 shdr.sh_offset = 0x500;
1141 shdr.sh_size = 0x100;
1142 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1143 memory_.SetMemory(0x500, ".eh_frame");
1144
1145 sh_offset += sizeof(shdr);
1146 memset(&shdr, 0, sizeof(shdr));
1147 shdr.sh_type = SHT_PROGBITS;
1148 shdr.sh_name = 0;
1149 shdr.sh_addr = 0x600;
1150 shdr.sh_offset = 0x600;
1151 shdr.sh_size = 0x200;
1152 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1153
1154 // CIE 32.
1155 memory_.SetData32(0x600, 0xfc);
1156 memory_.SetData32(0x604, 0);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001157 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001158
1159 // FDE 32.
1160 memory_.SetData32(0x700, 0xfc);
1161 memory_.SetData32(0x704, 0x104);
1162 memory_.SetData32(0x708, 0x20f8);
1163 memory_.SetData32(0x70c, 0x200);
1164
1165 uint64_t load_bias = 0;
1166 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris4cc36d22018-06-06 14:47:31 -07001167 elf->InitHeaders(0);
Christopher Ferris150db122017-12-20 18:49:01 -08001168 EXPECT_EQ(0U, load_bias);
1169 EXPECT_FALSE(elf->IsValidPc(0));
1170 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1171 EXPECT_TRUE(elf->IsValidPc(0x2800));
1172 EXPECT_TRUE(elf->IsValidPc(0x2900));
1173 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1174 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1175}
1176
Florian Mayerda459e52018-11-23 16:56:17 +00001177template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1178void ElfInterfaceTest::BuildID() {
1179 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1180
1181 uint64_t offset = 0x2000;
1182
1183 Ehdr ehdr = {};
1184 ehdr.e_shoff = offset;
1185 ehdr.e_shnum = 3;
1186 ehdr.e_shentsize = sizeof(Shdr);
1187 ehdr.e_shstrndx = 2;
1188 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1189
1190 offset += ehdr.e_shentsize;
1191
1192 char note_section[128];
1193 Nhdr note_header = {};
1194 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001195 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001196 note_header.n_type = NT_GNU_BUILD_ID;
1197 memcpy(&note_section, &note_header, sizeof(note_header));
1198 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001199 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001200 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1201 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001202 // This part of the note does not contain any trailing '\0'.
1203 memcpy(&note_section[note_offset], "BUILDID", 7);
1204 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001205
1206 Shdr shdr = {};
1207 shdr.sh_type = SHT_NOTE;
1208 shdr.sh_name = 0x500;
1209 shdr.sh_offset = 0xb000;
1210 shdr.sh_size = sizeof(note_section);
1211 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1212 offset += ehdr.e_shentsize;
1213
1214 // The string data for section header names.
1215 memset(&shdr, 0, sizeof(shdr));
1216 shdr.sh_type = SHT_STRTAB;
1217 shdr.sh_name = 0x20000;
1218 shdr.sh_offset = 0xf000;
1219 shdr.sh_size = 0x1000;
1220 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1221 offset += ehdr.e_shentsize;
1222
1223 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1224 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1225
1226 uint64_t load_bias = 0;
1227 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001228 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001229}
1230
1231template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1232void ElfInterfaceTest::BuildIDTwoNotes() {
1233 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1234
1235 uint64_t offset = 0x2000;
1236
1237 Ehdr ehdr = {};
1238 ehdr.e_shoff = offset;
1239 ehdr.e_shnum = 3;
1240 ehdr.e_shentsize = sizeof(Shdr);
1241 ehdr.e_shstrndx = 2;
1242 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1243
1244 offset += ehdr.e_shentsize;
1245
1246 char note_section[128];
1247 Nhdr note_header = {};
1248 note_header.n_namesz = 8; // "WRONG" aligned to 4
Christopher Ferris1760b452019-04-03 14:14:30 -07001249 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001250 note_header.n_type = NT_GNU_BUILD_ID;
1251 memcpy(&note_section, &note_header, sizeof(note_header));
1252 size_t note_offset = sizeof(note_header);
1253 memcpy(&note_section[note_offset], "WRONG", sizeof("WRONG"));
1254 note_offset += 8;
Christopher Ferris1760b452019-04-03 14:14:30 -07001255 // This part of the note does not contain any trailing '\0'.
1256 memcpy(&note_section[note_offset], "BUILDID", 7);
1257 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001258
1259 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001260 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001261 note_header.n_type = NT_GNU_BUILD_ID;
1262 memcpy(&note_section[note_offset], &note_header, sizeof(note_header));
1263 note_offset += sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001264 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001265 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1266 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001267 // This part of the note does not contain any trailing '\0'.
1268 memcpy(&note_section[note_offset], "BUILDID", 7);
1269 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001270
1271 Shdr shdr = {};
1272 shdr.sh_type = SHT_NOTE;
1273 shdr.sh_name = 0x500;
1274 shdr.sh_offset = 0xb000;
1275 shdr.sh_size = sizeof(note_section);
1276 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1277 offset += ehdr.e_shentsize;
1278
1279 // The string data for section header names.
1280 memset(&shdr, 0, sizeof(shdr));
1281 shdr.sh_type = SHT_STRTAB;
1282 shdr.sh_name = 0x20000;
1283 shdr.sh_offset = 0xf000;
1284 shdr.sh_size = 0x1000;
1285 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1286 offset += ehdr.e_shentsize;
1287
1288 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1289 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1290
1291 uint64_t load_bias = 0;
1292 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001293 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001294}
1295
1296template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1297void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1298 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1299
1300 uint64_t offset = 0x2000;
1301
1302 Ehdr ehdr = {};
1303 ehdr.e_shoff = offset;
1304 ehdr.e_shnum = 3;
1305 ehdr.e_shentsize = sizeof(Shdr);
1306 ehdr.e_shstrndx = 2;
1307 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1308
1309 offset += ehdr.e_shentsize;
1310
1311 char note_section[128];
1312 Nhdr note_header = {};
1313 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001314 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001315 note_header.n_type = NT_GNU_BUILD_ID;
1316 memcpy(&note_section, &note_header, sizeof(note_header));
1317 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001318 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001319 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1320 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001321 // This part of the note does not contain any trailing '\0'.
1322 memcpy(&note_section[note_offset], "BUILDID", 7);
1323 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001324
1325 Shdr shdr = {};
1326 shdr.sh_type = SHT_NOTE;
1327 shdr.sh_name = 0x500;
1328 shdr.sh_offset = 0xb000;
1329 shdr.sh_size = sizeof(note_header) + 1;
1330 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1331 offset += ehdr.e_shentsize;
1332
1333 // The string data for section header names.
1334 memset(&shdr, 0, sizeof(shdr));
1335 shdr.sh_type = SHT_STRTAB;
1336 shdr.sh_name = 0x20000;
1337 shdr.sh_offset = 0xf000;
1338 shdr.sh_size = 0x1000;
1339 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1340 offset += ehdr.e_shentsize;
1341
1342 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1343 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1344
1345 uint64_t load_bias = 0;
1346 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001347 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001348}
1349
1350template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1351void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1352 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1353
1354 uint64_t offset = 0x2000;
1355
1356 Ehdr ehdr = {};
1357 ehdr.e_shoff = offset;
1358 ehdr.e_shnum = 3;
1359 ehdr.e_shentsize = sizeof(Shdr);
1360 ehdr.e_shstrndx = 2;
1361 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1362
1363 offset += ehdr.e_shentsize;
1364
1365 char note_section[128];
1366 Nhdr note_header = {};
1367 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001368 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001369 note_header.n_type = NT_GNU_BUILD_ID;
1370 memcpy(&note_section, &note_header, sizeof(note_header));
1371 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001372 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001373 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1374 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001375 // This part of the note does not contain any trailing '\0'.
1376 memcpy(&note_section[note_offset], "BUILDID", 7);
1377 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001378
1379 Shdr shdr = {};
1380 shdr.sh_type = SHT_NOTE;
1381 shdr.sh_name = 0x500;
1382 shdr.sh_offset = 0xb000;
1383 shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1384 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1385 offset += ehdr.e_shentsize;
1386
1387 // The string data for section header names.
1388 memset(&shdr, 0, sizeof(shdr));
1389 shdr.sh_type = SHT_STRTAB;
1390 shdr.sh_name = 0x20000;
1391 shdr.sh_offset = 0xf000;
1392 shdr.sh_size = 0x1000;
1393 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1394 offset += ehdr.e_shentsize;
1395
1396 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1397 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1398
1399 uint64_t load_bias = 0;
1400 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001401 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001402}
1403
1404template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1405void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1406 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1407
1408 uint64_t offset = 0x2000;
1409
1410 Ehdr ehdr = {};
1411 ehdr.e_shoff = offset;
1412 ehdr.e_shnum = 3;
1413 ehdr.e_shentsize = sizeof(Shdr);
1414 ehdr.e_shstrndx = 2;
1415 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1416
1417 offset += ehdr.e_shentsize;
1418
1419 char note_section[128];
1420 Nhdr note_header = {};
1421 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001422 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001423 note_header.n_type = NT_GNU_BUILD_ID;
1424 memcpy(&note_section, &note_header, sizeof(note_header));
1425 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001426 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001427 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1428 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001429 // This part of the note does not contain any trailing '\0'.
1430 memcpy(&note_section[note_offset], "BUILDID", 7);
1431 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001432
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));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001455 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001456}
1457
1458TEST_F(ElfInterfaceTest, build_id32) {
1459 BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1460}
1461
1462TEST_F(ElfInterfaceTest, build_id64) {
1463 BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1464}
1465
1466TEST_F(ElfInterfaceTest, build_id_two_notes32) {
1467 BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1468}
1469
1470TEST_F(ElfInterfaceTest, build_id_two_notes64) {
1471 BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1472}
1473
1474TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name32) {
1475 BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1476}
1477
1478TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name64) {
1479 BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1480}
1481
1482TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc32) {
1483 BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1484}
1485
1486TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc64) {
1487 BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1488}
1489
1490TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header32) {
1491 BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1492}
1493
1494TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header64) {
1495 BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1496}
1497
Christopher Ferrisd226a512017-07-14 10:37:19 -07001498} // namespace unwindstack