blob: ea27e3ec6738db3ef9998dd82dbe585989e2072d [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
Christopher Ferris819f1312019-10-03 13:35:48 -0700115 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
116 void InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
117 int64_t expected_bias);
118
119 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
120 void InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr, uint64_t offset,
121 int64_t expected_bias);
122
123 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
124 void InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr, uint64_t offset,
125 int64_t expected_bias);
126
127 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
128 void CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias);
129
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700130 template <typename Sym>
131 void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
132 uint64_t sym_offset, const char* name);
133
Florian Mayerda459e52018-11-23 16:56:17 +0000134 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
135 void BuildID();
136
137 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
138 void BuildIDTwoNotes();
139
140 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
141 void BuildIDSectionTooSmallForName();
142
143 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
144 void BuildIDSectionTooSmallForDesc();
145
146 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
147 void BuildIDSectionTooSmallForHeader();
148
Christopher Ferris6c8ac562019-10-02 17:41:16 -0700149 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
Christopher Ferris819f1312019-10-03 13:35:48 -0700150 void CheckLoadBiasInFirstPhdr(int64_t load_bias);
Christopher Ferris6c8ac562019-10-02 17:41:16 -0700151
152 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
Christopher Ferris819f1312019-10-03 13:35:48 -0700153 void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, int64_t load_bias);
Christopher Ferris6c8ac562019-10-02 17:41:16 -0700154
Christopher Ferris3958f802017-02-01 15:44:40 -0800155 MemoryFake memory_;
156};
157
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700158template <typename Sym>
159void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
160 uint64_t sym_offset, const char* name) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700161 Sym sym = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700162 sym.st_info = STT_FUNC;
163 sym.st_value = value;
164 sym.st_size = size;
165 sym.st_name = name_offset;
166 sym.st_shndx = SHN_COMMON;
167
168 memory_.SetMemory(offset, &sym, sizeof(sym));
169 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
170}
171
Christopher Ferris3958f802017-02-01 15:44:40 -0800172template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
173void ElfInterfaceTest::SinglePtLoad() {
174 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
175
Christopher Ferrisf882a382018-06-22 16:48:02 -0700176 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800177 ehdr.e_phoff = 0x100;
178 ehdr.e_phnum = 1;
179 ehdr.e_phentsize = sizeof(Phdr);
180 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
181
Christopher Ferrisf882a382018-06-22 16:48:02 -0700182 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800183 phdr.p_type = PT_LOAD;
184 phdr.p_vaddr = 0x2000;
185 phdr.p_memsz = 0x10000;
186 phdr.p_flags = PF_R | PF_X;
187 phdr.p_align = 0x1000;
188 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
189
Christopher Ferris819f1312019-10-03 13:35:48 -0700190 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700191 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700192 EXPECT_EQ(0x2000, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800193
194 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
195 ASSERT_EQ(1U, pt_loads.size());
196 LoadInfo load_data = pt_loads.at(0);
197 ASSERT_EQ(0U, load_data.offset);
198 ASSERT_EQ(0x2000U, load_data.table_offset);
199 ASSERT_EQ(0x10000U, load_data.table_size);
200}
201
Christopher Ferris819f1312019-10-03 13:35:48 -0700202TEST_F(ElfInterfaceTest, single_pt_load_32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800203 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
204}
205
Christopher Ferris819f1312019-10-03 13:35:48 -0700206TEST_F(ElfInterfaceTest, single_pt_load_64) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800207 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
208}
209
210template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
211void ElfInterfaceTest::MultipleExecutablePtLoads() {
212 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
213
Christopher Ferrisf882a382018-06-22 16:48:02 -0700214 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800215 ehdr.e_phoff = 0x100;
216 ehdr.e_phnum = 3;
217 ehdr.e_phentsize = sizeof(Phdr);
218 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
219
Christopher Ferrisf882a382018-06-22 16:48:02 -0700220 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800221 phdr.p_type = PT_LOAD;
222 phdr.p_vaddr = 0x2000;
223 phdr.p_memsz = 0x10000;
224 phdr.p_flags = PF_R | PF_X;
225 phdr.p_align = 0x1000;
226 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
227
228 memset(&phdr, 0, sizeof(phdr));
229 phdr.p_type = PT_LOAD;
230 phdr.p_offset = 0x1000;
231 phdr.p_vaddr = 0x2001;
232 phdr.p_memsz = 0x10001;
233 phdr.p_flags = PF_R | PF_X;
234 phdr.p_align = 0x1001;
235 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
236
237 memset(&phdr, 0, sizeof(phdr));
238 phdr.p_type = PT_LOAD;
239 phdr.p_offset = 0x2000;
240 phdr.p_vaddr = 0x2002;
241 phdr.p_memsz = 0x10002;
242 phdr.p_flags = PF_R | PF_X;
243 phdr.p_align = 0x1002;
244 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
245
Christopher Ferris819f1312019-10-03 13:35:48 -0700246 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700247 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700248 EXPECT_EQ(0x2000, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800249
250 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
251 ASSERT_EQ(3U, pt_loads.size());
252
253 LoadInfo load_data = pt_loads.at(0);
254 ASSERT_EQ(0U, load_data.offset);
255 ASSERT_EQ(0x2000U, load_data.table_offset);
256 ASSERT_EQ(0x10000U, load_data.table_size);
257
258 load_data = pt_loads.at(0x1000);
259 ASSERT_EQ(0x1000U, load_data.offset);
260 ASSERT_EQ(0x2001U, load_data.table_offset);
261 ASSERT_EQ(0x10001U, load_data.table_size);
262
263 load_data = pt_loads.at(0x2000);
264 ASSERT_EQ(0x2000U, load_data.offset);
265 ASSERT_EQ(0x2002U, load_data.table_offset);
266 ASSERT_EQ(0x10002U, load_data.table_size);
267}
268
Christopher Ferris819f1312019-10-03 13:35:48 -0700269TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800270 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
271}
272
Christopher Ferris819f1312019-10-03 13:35:48 -0700273TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_64) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800274 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
275}
276
277template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
278void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
279 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
280
Christopher Ferrisf882a382018-06-22 16:48:02 -0700281 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800282 ehdr.e_phoff = 0x100;
283 ehdr.e_phnum = 3;
284 ehdr.e_phentsize = sizeof(Phdr) + 100;
285 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
286
Christopher Ferrisf882a382018-06-22 16:48:02 -0700287 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800288 phdr.p_type = PT_LOAD;
289 phdr.p_vaddr = 0x2000;
290 phdr.p_memsz = 0x10000;
291 phdr.p_flags = PF_R | PF_X;
292 phdr.p_align = 0x1000;
293 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
294
295 memset(&phdr, 0, sizeof(phdr));
296 phdr.p_type = PT_LOAD;
297 phdr.p_offset = 0x1000;
298 phdr.p_vaddr = 0x2001;
299 phdr.p_memsz = 0x10001;
300 phdr.p_flags = PF_R | PF_X;
301 phdr.p_align = 0x1001;
302 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
303
304 memset(&phdr, 0, sizeof(phdr));
305 phdr.p_type = PT_LOAD;
306 phdr.p_offset = 0x2000;
307 phdr.p_vaddr = 0x2002;
308 phdr.p_memsz = 0x10002;
309 phdr.p_flags = PF_R | PF_X;
310 phdr.p_align = 0x1002;
311 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
312
Christopher Ferris819f1312019-10-03 13:35:48 -0700313 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700314 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700315 EXPECT_EQ(0x2000, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800316
317 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
318 ASSERT_EQ(3U, pt_loads.size());
319
320 LoadInfo load_data = pt_loads.at(0);
321 ASSERT_EQ(0U, load_data.offset);
322 ASSERT_EQ(0x2000U, load_data.table_offset);
323 ASSERT_EQ(0x10000U, load_data.table_size);
324
325 load_data = pt_loads.at(0x1000);
326 ASSERT_EQ(0x1000U, load_data.offset);
327 ASSERT_EQ(0x2001U, load_data.table_offset);
328 ASSERT_EQ(0x10001U, load_data.table_size);
329
330 load_data = pt_loads.at(0x2000);
331 ASSERT_EQ(0x2000U, load_data.offset);
332 ASSERT_EQ(0x2002U, load_data.table_offset);
333 ASSERT_EQ(0x10002U, load_data.table_size);
334}
335
Christopher Ferris819f1312019-10-03 13:35:48 -0700336TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800337 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
338 ElfInterface32>();
339}
340
Christopher Ferris819f1312019-10-03 13:35:48 -0700341TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_64) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800342 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
343 ElfInterface64>();
344}
345
346template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
347void ElfInterfaceTest::NonExecutablePtLoads() {
348 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
349
Christopher Ferrisf882a382018-06-22 16:48:02 -0700350 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800351 ehdr.e_phoff = 0x100;
352 ehdr.e_phnum = 3;
353 ehdr.e_phentsize = sizeof(Phdr);
354 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
355
Christopher Ferrisf882a382018-06-22 16:48:02 -0700356 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800357 phdr.p_type = PT_LOAD;
358 phdr.p_vaddr = 0x2000;
359 phdr.p_memsz = 0x10000;
360 phdr.p_flags = PF_R;
361 phdr.p_align = 0x1000;
362 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
363
364 memset(&phdr, 0, sizeof(phdr));
365 phdr.p_type = PT_LOAD;
366 phdr.p_offset = 0x1000;
367 phdr.p_vaddr = 0x2001;
368 phdr.p_memsz = 0x10001;
369 phdr.p_flags = PF_R | PF_X;
370 phdr.p_align = 0x1001;
371 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
372
373 memset(&phdr, 0, sizeof(phdr));
374 phdr.p_type = PT_LOAD;
375 phdr.p_offset = 0x2000;
376 phdr.p_vaddr = 0x2002;
377 phdr.p_memsz = 0x10002;
378 phdr.p_flags = PF_R;
379 phdr.p_align = 0x1002;
380 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
381
Christopher Ferris819f1312019-10-03 13:35:48 -0700382 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700383 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700384 EXPECT_EQ(0x1001, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800385
386 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
387 ASSERT_EQ(1U, pt_loads.size());
388
389 LoadInfo load_data = pt_loads.at(0x1000);
390 ASSERT_EQ(0x1000U, load_data.offset);
391 ASSERT_EQ(0x2001U, load_data.table_offset);
392 ASSERT_EQ(0x10001U, load_data.table_size);
393}
394
Christopher Ferris819f1312019-10-03 13:35:48 -0700395TEST_F(ElfInterfaceTest, non_executable_pt_loads_32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800396 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
397}
398
Christopher Ferris819f1312019-10-03 13:35:48 -0700399TEST_F(ElfInterfaceTest, non_executable_pt_loads_64) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800400 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
401}
402
403template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
404void ElfInterfaceTest::ManyPhdrs() {
405 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
406
Christopher Ferrisf882a382018-06-22 16:48:02 -0700407 Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800408 ehdr.e_phoff = 0x100;
409 ehdr.e_phnum = 7;
410 ehdr.e_phentsize = sizeof(Phdr);
411 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
412
Christopher Ferris3958f802017-02-01 15:44:40 -0800413 uint64_t phdr_offset = 0x100;
414
Christopher Ferrisf882a382018-06-22 16:48:02 -0700415 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800416 phdr.p_type = PT_LOAD;
417 phdr.p_vaddr = 0x2000;
418 phdr.p_memsz = 0x10000;
419 phdr.p_flags = PF_R | PF_X;
420 phdr.p_align = 0x1000;
421 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
422 phdr_offset += sizeof(phdr);
423
424 memset(&phdr, 0, sizeof(phdr));
425 phdr.p_type = PT_GNU_EH_FRAME;
426 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
427 phdr_offset += sizeof(phdr);
428
429 memset(&phdr, 0, sizeof(phdr));
430 phdr.p_type = PT_DYNAMIC;
431 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
432 phdr_offset += sizeof(phdr);
433
434 memset(&phdr, 0, sizeof(phdr));
435 phdr.p_type = PT_INTERP;
436 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
437 phdr_offset += sizeof(phdr);
438
439 memset(&phdr, 0, sizeof(phdr));
440 phdr.p_type = PT_NOTE;
441 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
442 phdr_offset += sizeof(phdr);
443
444 memset(&phdr, 0, sizeof(phdr));
445 phdr.p_type = PT_SHLIB;
446 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
447 phdr_offset += sizeof(phdr);
448
449 memset(&phdr, 0, sizeof(phdr));
450 phdr.p_type = PT_GNU_EH_FRAME;
451 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
Christopher Ferris3958f802017-02-01 15:44:40 -0800452
Christopher Ferris819f1312019-10-03 13:35:48 -0700453 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700454 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700455 EXPECT_EQ(0x2000, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800456
457 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
458 ASSERT_EQ(1U, pt_loads.size());
459
460 LoadInfo load_data = pt_loads.at(0);
461 ASSERT_EQ(0U, load_data.offset);
462 ASSERT_EQ(0x2000U, load_data.table_offset);
463 ASSERT_EQ(0x10000U, load_data.table_size);
464}
465
Christopher Ferris819f1312019-10-03 13:35:48 -0700466TEST_F(ElfInterfaceTest, many_phdrs_32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800467 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
468}
469
Christopher Ferris819f1312019-10-03 13:35:48 -0700470TEST_F(ElfInterfaceTest, many_phdrs_64) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800471 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
472}
473
Christopher Ferris819f1312019-10-03 13:35:48 -0700474TEST_F(ElfInterfaceTest, arm32) {
Christopher Ferris3958f802017-02-01 15:44:40 -0800475 ElfInterfaceArm elf_arm(&memory_);
476
Christopher Ferrisf882a382018-06-22 16:48:02 -0700477 Elf32_Ehdr ehdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800478 ehdr.e_phoff = 0x100;
479 ehdr.e_phnum = 1;
480 ehdr.e_phentsize = sizeof(Elf32_Phdr);
481 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
482
Christopher Ferrisf882a382018-06-22 16:48:02 -0700483 Elf32_Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800484 phdr.p_type = PT_ARM_EXIDX;
Christopher Ferrisf882a382018-06-22 16:48:02 -0700485 phdr.p_offset = 0x2000;
486 phdr.p_filesz = 16;
Christopher Ferris3958f802017-02-01 15:44:40 -0800487 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
488
489 // Add arm exidx entries.
490 memory_.SetData32(0x2000, 0x1000);
491 memory_.SetData32(0x2008, 0x1000);
492
Christopher Ferris819f1312019-10-03 13:35:48 -0700493 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700494 ASSERT_TRUE(elf_arm.Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700495 EXPECT_EQ(0, load_bias);
Christopher Ferris3958f802017-02-01 15:44:40 -0800496
497 std::vector<uint32_t> entries;
498 for (auto addr : elf_arm) {
499 entries.push_back(addr);
500 }
501 ASSERT_EQ(2U, entries.size());
502 ASSERT_EQ(0x3000U, entries[0]);
503 ASSERT_EQ(0x3008U, entries[1]);
504
505 ASSERT_EQ(0x2000U, elf_arm.start_offset());
506 ASSERT_EQ(2U, elf_arm.total_entries());
507}
508
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800509template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
510void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
Christopher Ferrisf882a382018-06-22 16:48:02 -0700511 Ehdr ehdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800512 ehdr.e_shoff = 0x200;
513 ehdr.e_shnum = 2;
514 ehdr.e_shentsize = sizeof(Shdr);
Christopher Ferris3958f802017-02-01 15:44:40 -0800515 ehdr.e_phoff = 0x100;
516 ehdr.e_phnum = 1;
517 ehdr.e_phentsize = sizeof(Phdr);
518 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
519
Christopher Ferrisf882a382018-06-22 16:48:02 -0700520 Shdr shdr = {};
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800521 shdr.sh_type = SHT_STRTAB;
522 if (test_type == SONAME_MISSING_MAP) {
523 shdr.sh_addr = 0x20100;
524 } else {
525 shdr.sh_addr = 0x10100;
526 }
527 shdr.sh_offset = 0x10000;
528 memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
529
Christopher Ferrisf882a382018-06-22 16:48:02 -0700530 Phdr phdr = {};
Christopher Ferris3958f802017-02-01 15:44:40 -0800531 phdr.p_type = PT_DYNAMIC;
532 phdr.p_offset = 0x2000;
533 phdr.p_memsz = sizeof(Dyn) * 3;
534 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
535
536 uint64_t offset = 0x2000;
537 Dyn dyn;
538
539 dyn.d_tag = DT_STRTAB;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800540 dyn.d_un.d_ptr = 0x10100;
Christopher Ferris3958f802017-02-01 15:44:40 -0800541 memory_.SetMemory(offset, &dyn, sizeof(dyn));
542 offset += sizeof(dyn);
543
544 dyn.d_tag = DT_STRSZ;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800545 if (test_type == SONAME_DTSIZE_SMALL) {
546 dyn.d_un.d_val = 0x10;
547 } else {
548 dyn.d_un.d_val = 0x1000;
549 }
Christopher Ferris3958f802017-02-01 15:44:40 -0800550 memory_.SetMemory(offset, &dyn, sizeof(dyn));
551 offset += sizeof(dyn);
552
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800553 if (test_type == SONAME_DTNULL_AFTER) {
554 dyn.d_tag = DT_NULL;
555 memory_.SetMemory(offset, &dyn, sizeof(dyn));
556 offset += sizeof(dyn);
557 }
558
Christopher Ferris3958f802017-02-01 15:44:40 -0800559 dyn.d_tag = DT_SONAME;
560 dyn.d_un.d_val = 0x10;
561 memory_.SetMemory(offset, &dyn, sizeof(dyn));
562 offset += sizeof(dyn);
563
564 dyn.d_tag = DT_NULL;
565 memory_.SetMemory(offset, &dyn, sizeof(dyn));
566
567 SetStringMemory(0x10010, "fake_soname.so");
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800568}
569
570template <typename ElfInterfaceType>
571void ElfInterfaceTest::Soname() {
572 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
Christopher Ferris3958f802017-02-01 15:44:40 -0800573
Christopher Ferris819f1312019-10-03 13:35:48 -0700574 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700575 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700576 EXPECT_EQ(0, load_bias);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700577
Christopher Ferris02a6c442019-03-11 14:43:33 -0700578 ASSERT_EQ("fake_soname.so", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800579}
580
Christopher Ferris819f1312019-10-03 13:35:48 -0700581TEST_F(ElfInterfaceTest, soname_32) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800582 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
583 Soname<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800584}
585
Christopher Ferris819f1312019-10-03 13:35:48 -0700586TEST_F(ElfInterfaceTest, soname_64) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800587 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
588 Soname<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800589}
590
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800591template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800592void ElfInterfaceTest::SonameAfterDtNull() {
593 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
594
Christopher Ferris819f1312019-10-03 13:35:48 -0700595 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700596 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700597 EXPECT_EQ(0, load_bias);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700598
Christopher Ferris02a6c442019-03-11 14:43:33 -0700599 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800600}
601
Christopher Ferris819f1312019-10-03 13:35:48 -0700602TEST_F(ElfInterfaceTest, soname_after_dt_null_32) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800603 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
604 SonameAfterDtNull<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800605}
606
Christopher Ferris819f1312019-10-03 13:35:48 -0700607TEST_F(ElfInterfaceTest, soname_after_dt_null_64) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800608 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
609 SonameAfterDtNull<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800610}
611
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800612template <typename ElfInterfaceType>
Christopher Ferris3958f802017-02-01 15:44:40 -0800613void ElfInterfaceTest::SonameSize() {
614 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
615
Christopher Ferris819f1312019-10-03 13:35:48 -0700616 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700617 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700618 EXPECT_EQ(0, load_bias);
Christopher Ferrise69f4702017-10-19 16:08:58 -0700619
Christopher Ferris02a6c442019-03-11 14:43:33 -0700620 ASSERT_EQ("", elf->GetSoname());
Christopher Ferris3958f802017-02-01 15:44:40 -0800621}
622
Christopher Ferris819f1312019-10-03 13:35:48 -0700623TEST_F(ElfInterfaceTest, soname_size_32) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800624 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
625 SonameSize<ElfInterface32>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800626}
627
Christopher Ferris819f1312019-10-03 13:35:48 -0700628TEST_F(ElfInterfaceTest, soname_size_64) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800629 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
630 SonameSize<ElfInterface64>();
631}
632
633// Verify that there is no map from STRTAB in the dynamic section to a
634// STRTAB entry in the section headers.
635template <typename ElfInterfaceType>
636void ElfInterfaceTest::SonameMissingMap() {
637 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
638
Christopher Ferris819f1312019-10-03 13:35:48 -0700639 int64_t load_bias = 0;
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800640 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700641 EXPECT_EQ(0, load_bias);
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800642
Christopher Ferris02a6c442019-03-11 14:43:33 -0700643 ASSERT_EQ("", elf->GetSoname());
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800644}
645
Christopher Ferris819f1312019-10-03 13:35:48 -0700646TEST_F(ElfInterfaceTest, soname_missing_map_32) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800647 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
648 SonameMissingMap<ElfInterface32>();
649}
650
Christopher Ferris819f1312019-10-03 13:35:48 -0700651TEST_F(ElfInterfaceTest, soname_missing_map_64) {
Christopher Ferrisbeae42b2018-02-15 17:36:33 -0800652 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
653 SonameMissingMap<ElfInterface64>();
Christopher Ferris3958f802017-02-01 15:44:40 -0800654}
Christopher Ferris61d40972017-06-12 19:14:20 -0700655
Christopher Ferris61d40972017-06-12 19:14:20 -0700656template <typename ElfType>
657void ElfInterfaceTest::InitHeadersEhFrameTest() {
658 ElfType elf(&memory_);
659
Christopher Ferrise69f4702017-10-19 16:08:58 -0700660 elf.FakeSetEhFrameOffset(0x10000);
661 elf.FakeSetEhFrameSize(0);
662 elf.FakeSetDebugFrameOffset(0);
663 elf.FakeSetDebugFrameSize(0);
Christopher Ferris61d40972017-06-12 19:14:20 -0700664
665 memory_.SetMemory(0x10000,
666 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
667 memory_.SetData32(0x10004, 0x500);
668 memory_.SetData32(0x10008, 250);
669
Christopher Ferris819f1312019-10-03 13:35:48 -0700670 elf.InitHeaders();
Christopher Ferris61d40972017-06-12 19:14:20 -0700671
672 EXPECT_FALSE(elf.eh_frame() == nullptr);
673 EXPECT_TRUE(elf.debug_frame() == nullptr);
674}
675
Christopher Ferris819f1312019-10-03 13:35:48 -0700676TEST_F(ElfInterfaceTest, init_headers_eh_frame_32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700677 InitHeadersEhFrameTest<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700678}
679
Christopher Ferris819f1312019-10-03 13:35:48 -0700680TEST_F(ElfInterfaceTest, init_headers_eh_frame_64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700681 InitHeadersEhFrameTest<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700682}
683
684template <typename ElfType>
685void ElfInterfaceTest::InitHeadersDebugFrame() {
686 ElfType elf(&memory_);
687
Christopher Ferrise69f4702017-10-19 16:08:58 -0700688 elf.FakeSetEhFrameOffset(0);
689 elf.FakeSetEhFrameSize(0);
690 elf.FakeSetDebugFrameOffset(0x5000);
691 elf.FakeSetDebugFrameSize(0x200);
Christopher Ferris61d40972017-06-12 19:14:20 -0700692
693 memory_.SetData32(0x5000, 0xfc);
694 memory_.SetData32(0x5004, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -0700695 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
Christopher Ferris61d40972017-06-12 19:14:20 -0700696
697 memory_.SetData32(0x5100, 0xfc);
698 memory_.SetData32(0x5104, 0);
699 memory_.SetData32(0x5108, 0x1500);
700 memory_.SetData32(0x510c, 0x200);
701
Christopher Ferris819f1312019-10-03 13:35:48 -0700702 elf.InitHeaders();
Christopher Ferris61d40972017-06-12 19:14:20 -0700703
704 EXPECT_TRUE(elf.eh_frame() == nullptr);
705 EXPECT_FALSE(elf.debug_frame() == nullptr);
706}
707
Christopher Ferris819f1312019-10-03 13:35:48 -0700708TEST_F(ElfInterfaceTest, init_headers_debug_frame_32) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700709 InitHeadersDebugFrame<ElfInterface32Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700710}
711
Christopher Ferris819f1312019-10-03 13:35:48 -0700712TEST_F(ElfInterfaceTest, init_headers_debug_frame_64) {
Christopher Ferrise69f4702017-10-19 16:08:58 -0700713 InitHeadersDebugFrame<ElfInterface64Fake>();
Christopher Ferris61d40972017-06-12 19:14:20 -0700714}
715
Christopher Ferris5acf0692018-08-01 13:10:46 -0700716template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
717void ElfInterfaceTest::InitProgramHeadersMalformed() {
718 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
719
720 Ehdr ehdr = {};
721 ehdr.e_phoff = 0x100;
722 ehdr.e_phnum = 3;
723 ehdr.e_phentsize = sizeof(Phdr);
724 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
725
Christopher Ferris819f1312019-10-03 13:35:48 -0700726 int64_t load_bias = 0;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700727 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700728 EXPECT_EQ(0, load_bias);
Christopher Ferris5acf0692018-08-01 13:10:46 -0700729}
730
Christopher Ferris819f1312019-10-03 13:35:48 -0700731TEST_F(ElfInterfaceTest, init_program_headers_malformed_32) {
Christopher Ferris5acf0692018-08-01 13:10:46 -0700732 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
733}
734
Christopher Ferris819f1312019-10-03 13:35:48 -0700735TEST_F(ElfInterfaceTest, init_program_headers_malformed_64) {
Christopher Ferris5acf0692018-08-01 13:10:46 -0700736 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
737}
738
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700739template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
740void ElfInterfaceTest::InitSectionHeadersMalformed() {
741 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
742
Christopher Ferrisf882a382018-06-22 16:48:02 -0700743 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700744 ehdr.e_shoff = 0x1000;
745 ehdr.e_shnum = 10;
746 ehdr.e_shentsize = sizeof(Shdr);
747 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
748
Christopher Ferris819f1312019-10-03 13:35:48 -0700749 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700750 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700751 EXPECT_EQ(0, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700752}
753
Christopher Ferris819f1312019-10-03 13:35:48 -0700754TEST_F(ElfInterfaceTest, init_section_headers_malformed_32) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700755 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
756}
757
Christopher Ferris819f1312019-10-03 13:35:48 -0700758TEST_F(ElfInterfaceTest, init_section_headers_malformed_64) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700759 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
760}
761
Christopher Ferris5acf0692018-08-01 13:10:46 -0700762template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
763void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
764 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
765
766 uint64_t offset = 0x1000;
767
768 Ehdr ehdr = {};
769 ehdr.e_shoff = offset;
770 ehdr.e_shnum = 5;
771 ehdr.e_shentsize = sizeof(Shdr);
772 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
773
774 offset += ehdr.e_shentsize;
775
776 Shdr shdr = {};
777 shdr.sh_type = SHT_SYMTAB;
778 shdr.sh_link = 4;
779 shdr.sh_addr = 0x5000;
780 shdr.sh_offset = 0x5000;
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 memset(&shdr, 0, sizeof(shdr));
787 shdr.sh_type = SHT_DYNSYM;
788 shdr.sh_link = 10;
789 shdr.sh_addr = 0x6000;
790 shdr.sh_offset = 0x6000;
791 shdr.sh_entsize = 0x100;
792 shdr.sh_size = shdr.sh_entsize * 10;
793 memory_.SetMemory(offset, &shdr, sizeof(shdr));
794 offset += ehdr.e_shentsize;
795
796 memset(&shdr, 0, sizeof(shdr));
797 shdr.sh_type = SHT_DYNSYM;
798 shdr.sh_link = 2;
799 shdr.sh_addr = 0x6000;
800 shdr.sh_offset = 0x6000;
801 shdr.sh_entsize = 0x100;
802 shdr.sh_size = shdr.sh_entsize * 10;
803 memory_.SetMemory(offset, &shdr, sizeof(shdr));
804 offset += ehdr.e_shentsize;
805
806 // The string data for the entries.
807 memset(&shdr, 0, sizeof(shdr));
808 shdr.sh_type = SHT_STRTAB;
809 shdr.sh_name = 0x20000;
810 shdr.sh_offset = 0xf000;
811 shdr.sh_size = 0x1000;
812 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Christopher Ferris5acf0692018-08-01 13:10:46 -0700813
Christopher Ferris819f1312019-10-03 13:35:48 -0700814 int64_t load_bias = 0;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700815 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700816 EXPECT_EQ(0, load_bias);
Christopher Ferris5acf0692018-08-01 13:10:46 -0700817 EXPECT_EQ(0U, elf->debug_frame_offset());
818 EXPECT_EQ(0U, elf->debug_frame_size());
819 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
820 EXPECT_EQ(0U, elf->gnu_debugdata_size());
821
822 std::string name;
823 uint64_t name_offset;
824 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
825}
826
Christopher Ferris819f1312019-10-03 13:35:48 -0700827TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_32) {
Christopher Ferris5acf0692018-08-01 13:10:46 -0700828 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
829}
830
Christopher Ferris819f1312019-10-03 13:35:48 -0700831TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_64) {
Christopher Ferris5acf0692018-08-01 13:10:46 -0700832 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
833}
834
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700835template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
836void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
837 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
838
839 uint64_t offset = 0x1000;
840
Christopher Ferrisf882a382018-06-22 16:48:02 -0700841 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700842 ehdr.e_shoff = offset;
Christopher Ferris5acf0692018-08-01 13:10:46 -0700843 ehdr.e_shnum = 5;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700844 ehdr.e_shentsize = entry_size;
845 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
846
847 offset += ehdr.e_shentsize;
848
Christopher Ferrisf882a382018-06-22 16:48:02 -0700849 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700850 shdr.sh_type = SHT_SYMTAB;
851 shdr.sh_link = 4;
852 shdr.sh_addr = 0x5000;
853 shdr.sh_offset = 0x5000;
854 shdr.sh_entsize = sizeof(Sym);
855 shdr.sh_size = shdr.sh_entsize * 10;
856 memory_.SetMemory(offset, &shdr, sizeof(shdr));
857 offset += ehdr.e_shentsize;
858
859 memset(&shdr, 0, sizeof(shdr));
860 shdr.sh_type = SHT_DYNSYM;
861 shdr.sh_link = 4;
862 shdr.sh_addr = 0x6000;
863 shdr.sh_offset = 0x6000;
864 shdr.sh_entsize = sizeof(Sym);
865 shdr.sh_size = shdr.sh_entsize * 10;
866 memory_.SetMemory(offset, &shdr, sizeof(shdr));
867 offset += ehdr.e_shentsize;
868
869 memset(&shdr, 0, sizeof(shdr));
870 shdr.sh_type = SHT_PROGBITS;
871 shdr.sh_name = 0xa000;
872 memory_.SetMemory(offset, &shdr, sizeof(shdr));
873 offset += ehdr.e_shentsize;
874
875 // The string data for the entries.
876 memset(&shdr, 0, sizeof(shdr));
877 shdr.sh_type = SHT_STRTAB;
878 shdr.sh_name = 0x20000;
879 shdr.sh_offset = 0xf000;
880 shdr.sh_size = 0x1000;
881 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700882
883 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
884 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
885
Christopher Ferris819f1312019-10-03 13:35:48 -0700886 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -0700887 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -0700888 EXPECT_EQ(0, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700889 EXPECT_EQ(0U, elf->debug_frame_offset());
890 EXPECT_EQ(0U, elf->debug_frame_size());
891 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
892 EXPECT_EQ(0U, elf->gnu_debugdata_size());
893
894 // Look in the first symbol table.
895 std::string name;
896 uint64_t name_offset;
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700897 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700898 EXPECT_EQ("function_one", name);
899 EXPECT_EQ(16U, name_offset);
Christopher Ferris4cc36d22018-06-06 14:47:31 -0700900 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700901 EXPECT_EQ("function_two", name);
902 EXPECT_EQ(32U, name_offset);
903}
904
Christopher Ferris819f1312019-10-03 13:35:48 -0700905TEST_F(ElfInterfaceTest, init_section_headers_32) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700906 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
907}
908
Christopher Ferris819f1312019-10-03 13:35:48 -0700909TEST_F(ElfInterfaceTest, init_section_headers_64) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700910 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
911}
912
Christopher Ferris819f1312019-10-03 13:35:48 -0700913TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_32) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700914 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
915}
916
Christopher Ferris819f1312019-10-03 13:35:48 -0700917TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_64) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700918 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
919}
920
921template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
922void ElfInterfaceTest::InitSectionHeadersOffsets() {
923 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
924
925 uint64_t offset = 0x2000;
926
Christopher Ferrisf882a382018-06-22 16:48:02 -0700927 Ehdr ehdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700928 ehdr.e_shoff = offset;
Florian Mayerda459e52018-11-23 16:56:17 +0000929 ehdr.e_shnum = 7;
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700930 ehdr.e_shentsize = sizeof(Shdr);
931 ehdr.e_shstrndx = 2;
932 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
933
934 offset += ehdr.e_shentsize;
935
Christopher Ferrisf882a382018-06-22 16:48:02 -0700936 Shdr shdr = {};
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700937 shdr.sh_type = SHT_PROGBITS;
938 shdr.sh_link = 2;
939 shdr.sh_name = 0x200;
940 shdr.sh_addr = 0x5000;
941 shdr.sh_offset = 0x5000;
942 shdr.sh_entsize = 0x100;
943 shdr.sh_size = 0x800;
944 memory_.SetMemory(offset, &shdr, sizeof(shdr));
945 offset += ehdr.e_shentsize;
946
947 // The string data for section header names.
948 memset(&shdr, 0, sizeof(shdr));
949 shdr.sh_type = SHT_STRTAB;
950 shdr.sh_name = 0x20000;
951 shdr.sh_offset = 0xf000;
952 shdr.sh_size = 0x1000;
953 memory_.SetMemory(offset, &shdr, sizeof(shdr));
954 offset += ehdr.e_shentsize;
955
956 memset(&shdr, 0, sizeof(shdr));
957 shdr.sh_type = SHT_PROGBITS;
958 shdr.sh_link = 2;
959 shdr.sh_name = 0x100;
960 shdr.sh_addr = 0x6000;
961 shdr.sh_offset = 0x6000;
962 shdr.sh_entsize = 0x100;
963 shdr.sh_size = 0x500;
964 memory_.SetMemory(offset, &shdr, sizeof(shdr));
965 offset += ehdr.e_shentsize;
966
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700967 memset(&shdr, 0, sizeof(shdr));
968 shdr.sh_type = SHT_PROGBITS;
969 shdr.sh_link = 2;
970 shdr.sh_name = 0x300;
971 shdr.sh_addr = 0x7000;
972 shdr.sh_offset = 0x7000;
973 shdr.sh_entsize = 0x100;
974 shdr.sh_size = 0x800;
975 memory_.SetMemory(offset, &shdr, sizeof(shdr));
976 offset += ehdr.e_shentsize;
977
978 memset(&shdr, 0, sizeof(shdr));
979 shdr.sh_type = SHT_PROGBITS;
980 shdr.sh_link = 2;
981 shdr.sh_name = 0x400;
Christopher Ferris819f1312019-10-03 13:35:48 -0700982 shdr.sh_addr = 0xa000;
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700983 shdr.sh_offset = 0xa000;
984 shdr.sh_entsize = 0x100;
985 shdr.sh_size = 0xf00;
986 memory_.SetMemory(offset, &shdr, sizeof(shdr));
987 offset += ehdr.e_shentsize;
988
Florian Mayerda459e52018-11-23 16:56:17 +0000989 memset(&shdr, 0, sizeof(shdr));
990 shdr.sh_type = SHT_NOTE;
991 shdr.sh_name = 0x500;
Christopher Ferris819f1312019-10-03 13:35:48 -0700992 shdr.sh_addr = 0xb000;
Florian Mayerda459e52018-11-23 16:56:17 +0000993 shdr.sh_offset = 0xb000;
994 shdr.sh_size = 0xf00;
995 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +0000996
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700997 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
998 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
Christopher Ferrisc9dee842017-11-03 14:50:27 -0700999 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
1000 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
Florian Mayerda459e52018-11-23 16:56:17 +00001001 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001002
Christopher Ferris819f1312019-10-03 13:35:48 -07001003 int64_t load_bias = 0;
Christopher Ferrise69f4702017-10-19 16:08:58 -07001004 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -07001005 EXPECT_EQ(0, load_bias);
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001006 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
Christopher Ferris819f1312019-10-03 13:35:48 -07001007 EXPECT_EQ(0, elf->debug_frame_section_bias());
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001008 EXPECT_EQ(0x500U, elf->debug_frame_size());
Christopher Ferris819f1312019-10-03 13:35:48 -07001009
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001010 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
1011 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
Christopher Ferris819f1312019-10-03 13:35:48 -07001012
Christopher Ferrisc9dee842017-11-03 14:50:27 -07001013 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
Christopher Ferris819f1312019-10-03 13:35:48 -07001014 EXPECT_EQ(0, elf->eh_frame_section_bias());
Christopher Ferrisc9dee842017-11-03 14:50:27 -07001015 EXPECT_EQ(0x800U, elf->eh_frame_size());
Christopher Ferris819f1312019-10-03 13:35:48 -07001016
Christopher Ferrisc9dee842017-11-03 14:50:27 -07001017 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
Christopher Ferris819f1312019-10-03 13:35:48 -07001018 EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
Christopher Ferrisc9dee842017-11-03 14:50:27 -07001019 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
Christopher Ferris819f1312019-10-03 13:35:48 -07001020
Florian Mayerda459e52018-11-23 16:56:17 +00001021 EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
1022 EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001023}
1024
Christopher Ferris819f1312019-10-03 13:35:48 -07001025TEST_F(ElfInterfaceTest, init_section_headers_offsets_32) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001026 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1027}
1028
Christopher Ferris819f1312019-10-03 13:35:48 -07001029TEST_F(ElfInterfaceTest, init_section_headers_offsets_64) {
Christopher Ferris8098b1c2017-06-20 13:54:08 -07001030 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1031}
Christopher Ferrisd226a512017-07-14 10:37:19 -07001032
Christopher Ferris819f1312019-10-03 13:35:48 -07001033template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
1034void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
1035 int64_t expected_bias) {
1036 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1037
1038 uint64_t elf_offset = 0x2000;
1039
1040 Ehdr ehdr = {};
1041 ehdr.e_shoff = elf_offset;
1042 ehdr.e_shnum = 4;
1043 ehdr.e_shentsize = sizeof(Shdr);
1044 ehdr.e_shstrndx = 2;
1045 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1046
1047 elf_offset += ehdr.e_shentsize;
1048
1049 Shdr shdr = {};
1050 shdr.sh_type = SHT_PROGBITS;
1051 shdr.sh_link = 2;
1052 shdr.sh_name = 0x200;
1053 shdr.sh_addr = 0x8000;
1054 shdr.sh_offset = 0x8000;
1055 shdr.sh_entsize = 0x100;
1056 shdr.sh_size = 0x800;
1057 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1058 elf_offset += ehdr.e_shentsize;
1059
1060 // The string data for section header names.
1061 memset(&shdr, 0, sizeof(shdr));
1062 shdr.sh_type = SHT_STRTAB;
1063 shdr.sh_name = 0x20000;
1064 shdr.sh_offset = 0xf000;
1065 shdr.sh_size = 0x1000;
1066 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1067 elf_offset += ehdr.e_shentsize;
1068
1069 memset(&shdr, 0, sizeof(shdr));
1070 shdr.sh_type = SHT_PROGBITS;
1071 shdr.sh_link = 2;
1072 shdr.sh_name = 0x100;
1073 shdr.sh_addr = addr;
1074 shdr.sh_offset = offset;
1075 shdr.sh_entsize = 0x100;
1076 shdr.sh_size = 0x500;
1077 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1078
1079 memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1080 memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1081
1082 int64_t load_bias = 0;
1083 ASSERT_TRUE(elf->Init(&load_bias));
1084 EXPECT_EQ(0, load_bias);
1085 EXPECT_EQ(offset, elf->eh_frame_offset());
1086 EXPECT_EQ(expected_bias, elf->eh_frame_section_bias());
1087 EXPECT_EQ(0x500U, elf->eh_frame_size());
1088
1089 EXPECT_EQ(0x8000U, elf->eh_frame_hdr_offset());
1090 EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
1091 EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
1092}
1093
1094TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_32) {
1095 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x4000,
1096 0x4000, 0);
1097}
1098
1099TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_64) {
1100 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0x6000,
1101 0x6000, 0);
1102}
1103
1104TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_32) {
1105 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1106 0x5000, 0x4000, 0x1000);
1107}
1108
1109TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_64) {
1110 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1111 0x6000, 0x4000, 0x2000);
1112}
1113
1114TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_32) {
1115 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1116 0x3000, 0x4000, -0x1000);
1117}
1118
1119TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_64) {
1120 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1121 0x6000, 0x9000, -0x3000);
1122}
1123
1124template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
1125void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,
1126 uint64_t offset,
1127 int64_t expected_bias) {
1128 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1129
1130 uint64_t elf_offset = 0x2000;
1131
1132 Ehdr ehdr = {};
1133 ehdr.e_shoff = elf_offset;
1134 ehdr.e_shnum = 4;
1135 ehdr.e_shentsize = sizeof(Shdr);
1136 ehdr.e_shstrndx = 2;
1137 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1138
1139 elf_offset += ehdr.e_shentsize;
1140
1141 Shdr shdr = {};
1142 shdr.sh_type = SHT_PROGBITS;
1143 shdr.sh_link = 2;
1144 shdr.sh_name = 0x200;
1145 shdr.sh_addr = addr;
1146 shdr.sh_offset = offset;
1147 shdr.sh_entsize = 0x100;
1148 shdr.sh_size = 0x800;
1149 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1150 elf_offset += ehdr.e_shentsize;
1151
1152 // The string data for section header names.
1153 memset(&shdr, 0, sizeof(shdr));
1154 shdr.sh_type = SHT_STRTAB;
1155 shdr.sh_name = 0x20000;
1156 shdr.sh_offset = 0xf000;
1157 shdr.sh_size = 0x1000;
1158 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1159 elf_offset += ehdr.e_shentsize;
1160
1161 memset(&shdr, 0, sizeof(shdr));
1162 shdr.sh_type = SHT_PROGBITS;
1163 shdr.sh_link = 2;
1164 shdr.sh_name = 0x100;
1165 shdr.sh_addr = 0x5000;
1166 shdr.sh_offset = 0x5000;
1167 shdr.sh_entsize = 0x100;
1168 shdr.sh_size = 0x500;
1169 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1170
1171 memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1172 memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1173
1174 int64_t load_bias = 0;
1175 ASSERT_TRUE(elf->Init(&load_bias));
1176 EXPECT_EQ(0, load_bias);
1177 EXPECT_EQ(0x5000U, elf->eh_frame_offset());
1178 EXPECT_EQ(0, elf->eh_frame_section_bias());
1179 EXPECT_EQ(0x500U, elf->eh_frame_size());
1180 EXPECT_EQ(offset, elf->eh_frame_hdr_offset());
1181 EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
1182 EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
1183}
1184
1185TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32) {
1186 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x9000,
1187 0x9000, 0);
1188}
1189
1190TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64) {
1191 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1192 0xa000, 0);
1193}
1194
1195TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32) {
1196 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1197 0x9000, 0x4000, 0x5000);
1198}
1199
1200TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64) {
1201 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1202 0x6000, 0x1000, 0x5000);
1203}
1204
1205TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32) {
1206 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1207 0x3000, 0x5000, -0x2000);
1208}
1209
1210TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64) {
1211 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1212 0x5000, 0x9000, -0x4000);
1213}
1214
1215template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
1216void ElfInterfaceTest::InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,
1217 uint64_t offset,
1218 int64_t expected_bias) {
1219 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1220
1221 uint64_t elf_offset = 0x2000;
1222
1223 Ehdr ehdr = {};
1224 ehdr.e_shoff = elf_offset;
1225 ehdr.e_shnum = 3;
1226 ehdr.e_shentsize = sizeof(Shdr);
1227 ehdr.e_shstrndx = 2;
1228 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1229
1230 elf_offset += ehdr.e_shentsize;
1231
1232 Shdr shdr = {};
1233 shdr.sh_type = SHT_PROGBITS;
1234 shdr.sh_link = 2;
1235 shdr.sh_name = 0x100;
1236 shdr.sh_addr = addr;
1237 shdr.sh_offset = offset;
1238 shdr.sh_entsize = 0x100;
1239 shdr.sh_size = 0x800;
1240 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1241 elf_offset += ehdr.e_shentsize;
1242
1243 // The string data for section header names.
1244 memset(&shdr, 0, sizeof(shdr));
1245 shdr.sh_type = SHT_STRTAB;
1246 shdr.sh_name = 0x20000;
1247 shdr.sh_offset = 0xf000;
1248 shdr.sh_size = 0x1000;
1249 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1250
1251 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
1252
1253 int64_t load_bias = 0;
1254 ASSERT_TRUE(elf->Init(&load_bias));
1255 EXPECT_EQ(0, load_bias);
1256 EXPECT_EQ(offset, elf->debug_frame_offset());
1257 EXPECT_EQ(expected_bias, elf->debug_frame_section_bias());
1258 EXPECT_EQ(0x800U, elf->debug_frame_size());
1259}
1260
1261TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_32) {
1262 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x5000,
1263 0x5000, 0);
1264}
1265
1266TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_64) {
1267 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1268 0xa000, 0);
1269}
1270
1271TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_32) {
1272 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1273 0x5000, 0x2000, 0x3000);
1274}
1275
1276TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_64) {
1277 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1278 0x7000, 0x1000, 0x6000);
1279}
1280
1281TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_32) {
1282 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1283 0x6000, 0x7000, -0x1000);
1284}
1285
1286TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_64) {
1287 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1288 0x3000, 0x5000, -0x2000);
1289}
1290
1291template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
1292void ElfInterfaceTest::CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias) {
1293 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
1294
1295 Ehdr ehdr = {};
1296 ehdr.e_phoff = 0x100;
1297 ehdr.e_phnum = 2;
1298 ehdr.e_phentsize = sizeof(Phdr);
1299 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1300
1301 uint64_t phdr_offset = 0x100;
1302
1303 Phdr phdr = {};
1304 phdr.p_type = PT_LOAD;
1305 phdr.p_memsz = 0x10000;
1306 phdr.p_flags = PF_R | PF_X;
1307 phdr.p_align = 0x1000;
1308 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
1309 phdr_offset += sizeof(phdr);
1310
1311 memset(&phdr, 0, sizeof(phdr));
1312 phdr.p_type = PT_GNU_EH_FRAME;
Christopher Ferris5838e532019-10-21 18:59:42 -07001313 phdr.p_vaddr = addr;
Christopher Ferris819f1312019-10-03 13:35:48 -07001314 phdr.p_offset = offset;
1315 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
1316
1317 int64_t load_bias = 0;
1318 ASSERT_TRUE(elf->Init(&load_bias));
1319 EXPECT_EQ(0, load_bias);
1320 EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
1321}
1322
1323TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_32) {
1324 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x4000, 0);
1325}
1326
1327TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_64) {
1328 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x4000, 0);
1329}
1330
1331TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_32) {
1332 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x1000, 0x3000);
1333}
1334
1335TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_64) {
1336 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x1000, 0x3000);
1337}
1338
1339TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_32) {
1340 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x5000,
1341 -0x1000);
1342}
1343
1344TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_64) {
1345 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x5000,
1346 -0x1000);
1347}
1348
Christopher Ferris150db122017-12-20 18:49:01 -08001349TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
1350 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1351
Christopher Ferrisf882a382018-06-22 16:48:02 -07001352 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001353 ehdr.e_phoff = 0x100;
1354 ehdr.e_phnum = 1;
1355 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1356 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1357
Christopher Ferrisf882a382018-06-22 16:48:02 -07001358 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001359 phdr.p_type = PT_LOAD;
1360 phdr.p_vaddr = 0;
1361 phdr.p_memsz = 0x10000;
1362 phdr.p_flags = PF_R | PF_X;
1363 phdr.p_align = 0x1000;
1364 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1365
Christopher Ferris819f1312019-10-03 13:35:48 -07001366 int64_t load_bias = 0;
Christopher Ferris150db122017-12-20 18:49:01 -08001367 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -07001368 EXPECT_EQ(0, load_bias);
Christopher Ferris150db122017-12-20 18:49:01 -08001369 EXPECT_TRUE(elf->IsValidPc(0));
1370 EXPECT_TRUE(elf->IsValidPc(0x5000));
1371 EXPECT_TRUE(elf->IsValidPc(0xffff));
1372 EXPECT_FALSE(elf->IsValidPc(0x10000));
1373}
1374
1375TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1376 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1377
Christopher Ferrisf882a382018-06-22 16:48:02 -07001378 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001379 ehdr.e_phoff = 0x100;
1380 ehdr.e_phnum = 1;
1381 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1382 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1383
Christopher Ferrisf882a382018-06-22 16:48:02 -07001384 Elf32_Phdr phdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001385 phdr.p_type = PT_LOAD;
1386 phdr.p_vaddr = 0x2000;
1387 phdr.p_memsz = 0x10000;
1388 phdr.p_flags = PF_R | PF_X;
1389 phdr.p_align = 0x1000;
1390 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1391
Christopher Ferris819f1312019-10-03 13:35:48 -07001392 int64_t load_bias = 0;
Christopher Ferris150db122017-12-20 18:49:01 -08001393 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -07001394 EXPECT_EQ(0x2000, load_bias);
Christopher Ferris150db122017-12-20 18:49:01 -08001395 EXPECT_FALSE(elf->IsValidPc(0));
1396 EXPECT_FALSE(elf->IsValidPc(0x1000));
1397 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1398 EXPECT_TRUE(elf->IsValidPc(0x2000));
1399 EXPECT_TRUE(elf->IsValidPc(0x5000));
1400 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1401 EXPECT_FALSE(elf->IsValidPc(0x12000));
1402}
1403
1404TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1405 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1406
1407 uint64_t sh_offset = 0x100;
1408
Christopher Ferrisf882a382018-06-22 16:48:02 -07001409 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001410 ehdr.e_shstrndx = 1;
1411 ehdr.e_shoff = sh_offset;
1412 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1413 ehdr.e_shnum = 3;
1414 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1415
Christopher Ferrisf882a382018-06-22 16:48:02 -07001416 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001417 shdr.sh_type = SHT_NULL;
1418 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1419
1420 sh_offset += sizeof(shdr);
1421 memset(&shdr, 0, sizeof(shdr));
1422 shdr.sh_type = SHT_STRTAB;
1423 shdr.sh_name = 1;
1424 shdr.sh_offset = 0x500;
1425 shdr.sh_size = 0x100;
1426 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1427 memory_.SetMemory(0x500, ".debug_frame");
1428
1429 sh_offset += sizeof(shdr);
1430 memset(&shdr, 0, sizeof(shdr));
1431 shdr.sh_type = SHT_PROGBITS;
1432 shdr.sh_name = 0;
1433 shdr.sh_addr = 0x600;
1434 shdr.sh_offset = 0x600;
1435 shdr.sh_size = 0x200;
1436 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1437
1438 // CIE 32.
1439 memory_.SetData32(0x600, 0xfc);
1440 memory_.SetData32(0x604, 0xffffffff);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001441 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001442
1443 // FDE 32.
1444 memory_.SetData32(0x700, 0xfc);
1445 memory_.SetData32(0x704, 0);
1446 memory_.SetData32(0x708, 0x2100);
1447 memory_.SetData32(0x70c, 0x200);
1448
Christopher Ferris819f1312019-10-03 13:35:48 -07001449 int64_t load_bias = 0;
Christopher Ferris150db122017-12-20 18:49:01 -08001450 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -07001451 elf->InitHeaders();
1452 EXPECT_EQ(0, load_bias);
Christopher Ferris150db122017-12-20 18:49:01 -08001453 EXPECT_FALSE(elf->IsValidPc(0));
1454 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1455 EXPECT_TRUE(elf->IsValidPc(0x2100));
1456 EXPECT_TRUE(elf->IsValidPc(0x2200));
1457 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1458 EXPECT_FALSE(elf->IsValidPc(0x2300));
1459}
1460
1461TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1462 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1463
1464 uint64_t sh_offset = 0x100;
1465
Christopher Ferrisf882a382018-06-22 16:48:02 -07001466 Elf32_Ehdr ehdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001467 ehdr.e_shstrndx = 1;
1468 ehdr.e_shoff = sh_offset;
1469 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1470 ehdr.e_shnum = 3;
1471 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1472
Christopher Ferrisf882a382018-06-22 16:48:02 -07001473 Elf32_Shdr shdr = {};
Christopher Ferris150db122017-12-20 18:49:01 -08001474 shdr.sh_type = SHT_NULL;
1475 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1476
1477 sh_offset += sizeof(shdr);
1478 memset(&shdr, 0, sizeof(shdr));
1479 shdr.sh_type = SHT_STRTAB;
1480 shdr.sh_name = 1;
1481 shdr.sh_offset = 0x500;
1482 shdr.sh_size = 0x100;
1483 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1484 memory_.SetMemory(0x500, ".eh_frame");
1485
1486 sh_offset += sizeof(shdr);
1487 memset(&shdr, 0, sizeof(shdr));
1488 shdr.sh_type = SHT_PROGBITS;
1489 shdr.sh_name = 0;
1490 shdr.sh_addr = 0x600;
1491 shdr.sh_offset = 0x600;
1492 shdr.sh_size = 0x200;
1493 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1494
1495 // CIE 32.
1496 memory_.SetData32(0x600, 0xfc);
1497 memory_.SetData32(0x604, 0);
Christopher Ferris92acaac2018-06-21 10:44:02 -07001498 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
Christopher Ferris150db122017-12-20 18:49:01 -08001499
1500 // FDE 32.
1501 memory_.SetData32(0x700, 0xfc);
1502 memory_.SetData32(0x704, 0x104);
1503 memory_.SetData32(0x708, 0x20f8);
1504 memory_.SetData32(0x70c, 0x200);
1505
Christopher Ferris819f1312019-10-03 13:35:48 -07001506 int64_t load_bias = 0;
Christopher Ferris150db122017-12-20 18:49:01 -08001507 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferris819f1312019-10-03 13:35:48 -07001508 elf->InitHeaders();
1509 EXPECT_EQ(0, load_bias);
Christopher Ferris150db122017-12-20 18:49:01 -08001510 EXPECT_FALSE(elf->IsValidPc(0));
1511 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1512 EXPECT_TRUE(elf->IsValidPc(0x2800));
1513 EXPECT_TRUE(elf->IsValidPc(0x2900));
1514 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1515 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1516}
1517
Florian Mayerda459e52018-11-23 16:56:17 +00001518template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1519void ElfInterfaceTest::BuildID() {
1520 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1521
1522 uint64_t offset = 0x2000;
1523
1524 Ehdr ehdr = {};
1525 ehdr.e_shoff = offset;
1526 ehdr.e_shnum = 3;
1527 ehdr.e_shentsize = sizeof(Shdr);
1528 ehdr.e_shstrndx = 2;
1529 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1530
1531 offset += ehdr.e_shentsize;
1532
1533 char note_section[128];
1534 Nhdr note_header = {};
1535 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001536 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001537 note_header.n_type = NT_GNU_BUILD_ID;
1538 memcpy(&note_section, &note_header, sizeof(note_header));
1539 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001540 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001541 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1542 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001543 // This part of the note does not contain any trailing '\0'.
1544 memcpy(&note_section[note_offset], "BUILDID", 7);
Florian Mayerda459e52018-11-23 16:56:17 +00001545
1546 Shdr shdr = {};
1547 shdr.sh_type = SHT_NOTE;
1548 shdr.sh_name = 0x500;
1549 shdr.sh_offset = 0xb000;
1550 shdr.sh_size = sizeof(note_section);
1551 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1552 offset += ehdr.e_shentsize;
1553
1554 // The string data for section header names.
1555 memset(&shdr, 0, sizeof(shdr));
1556 shdr.sh_type = SHT_STRTAB;
1557 shdr.sh_name = 0x20000;
1558 shdr.sh_offset = 0xf000;
1559 shdr.sh_size = 0x1000;
1560 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +00001561
1562 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1563 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1564
Christopher Ferris819f1312019-10-03 13:35:48 -07001565 int64_t load_bias = 0;
Florian Mayerda459e52018-11-23 16:56:17 +00001566 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001567 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001568}
1569
Christopher Ferris819f1312019-10-03 13:35:48 -07001570TEST_F(ElfInterfaceTest, build_id_32) {
1571 BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1572}
1573
1574TEST_F(ElfInterfaceTest, build_id_64) {
1575 BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1576}
1577
Florian Mayerda459e52018-11-23 16:56:17 +00001578template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1579void ElfInterfaceTest::BuildIDTwoNotes() {
1580 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1581
1582 uint64_t offset = 0x2000;
1583
1584 Ehdr ehdr = {};
1585 ehdr.e_shoff = offset;
1586 ehdr.e_shnum = 3;
1587 ehdr.e_shentsize = sizeof(Shdr);
1588 ehdr.e_shstrndx = 2;
1589 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1590
1591 offset += ehdr.e_shentsize;
1592
1593 char note_section[128];
1594 Nhdr note_header = {};
1595 note_header.n_namesz = 8; // "WRONG" aligned to 4
Christopher Ferris1760b452019-04-03 14:14:30 -07001596 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001597 note_header.n_type = NT_GNU_BUILD_ID;
1598 memcpy(&note_section, &note_header, sizeof(note_header));
1599 size_t note_offset = sizeof(note_header);
1600 memcpy(&note_section[note_offset], "WRONG", sizeof("WRONG"));
1601 note_offset += 8;
Christopher Ferris1760b452019-04-03 14:14:30 -07001602 // This part of the note does not contain any trailing '\0'.
1603 memcpy(&note_section[note_offset], "BUILDID", 7);
1604 note_offset += 8;
Florian Mayerda459e52018-11-23 16:56:17 +00001605
1606 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001607 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001608 note_header.n_type = NT_GNU_BUILD_ID;
1609 memcpy(&note_section[note_offset], &note_header, sizeof(note_header));
1610 note_offset += sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001611 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001612 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1613 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001614 // This part of the note does not contain any trailing '\0'.
1615 memcpy(&note_section[note_offset], "BUILDID", 7);
Florian Mayerda459e52018-11-23 16:56:17 +00001616
1617 Shdr shdr = {};
1618 shdr.sh_type = SHT_NOTE;
1619 shdr.sh_name = 0x500;
1620 shdr.sh_offset = 0xb000;
1621 shdr.sh_size = sizeof(note_section);
1622 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1623 offset += ehdr.e_shentsize;
1624
1625 // The string data for section header names.
1626 memset(&shdr, 0, sizeof(shdr));
1627 shdr.sh_type = SHT_STRTAB;
1628 shdr.sh_name = 0x20000;
1629 shdr.sh_offset = 0xf000;
1630 shdr.sh_size = 0x1000;
1631 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +00001632
1633 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1634 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1635
Christopher Ferris819f1312019-10-03 13:35:48 -07001636 int64_t load_bias = 0;
Florian Mayerda459e52018-11-23 16:56:17 +00001637 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001638 ASSERT_EQ("BUILDID", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001639}
1640
Christopher Ferris819f1312019-10-03 13:35:48 -07001641TEST_F(ElfInterfaceTest, build_id_two_notes_32) {
1642 BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1643}
1644
1645TEST_F(ElfInterfaceTest, build_id_two_notes_64) {
1646 BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1647}
1648
Florian Mayerda459e52018-11-23 16:56:17 +00001649template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1650void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1651 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1652
1653 uint64_t offset = 0x2000;
1654
1655 Ehdr ehdr = {};
1656 ehdr.e_shoff = offset;
1657 ehdr.e_shnum = 3;
1658 ehdr.e_shentsize = sizeof(Shdr);
1659 ehdr.e_shstrndx = 2;
1660 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1661
1662 offset += ehdr.e_shentsize;
1663
1664 char note_section[128];
1665 Nhdr note_header = {};
1666 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001667 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001668 note_header.n_type = NT_GNU_BUILD_ID;
1669 memcpy(&note_section, &note_header, sizeof(note_header));
1670 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001671 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001672 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1673 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001674 // This part of the note does not contain any trailing '\0'.
1675 memcpy(&note_section[note_offset], "BUILDID", 7);
Florian Mayerda459e52018-11-23 16:56:17 +00001676
1677 Shdr shdr = {};
1678 shdr.sh_type = SHT_NOTE;
1679 shdr.sh_name = 0x500;
1680 shdr.sh_offset = 0xb000;
1681 shdr.sh_size = sizeof(note_header) + 1;
1682 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1683 offset += ehdr.e_shentsize;
1684
1685 // The string data for section header names.
1686 memset(&shdr, 0, sizeof(shdr));
1687 shdr.sh_type = SHT_STRTAB;
1688 shdr.sh_name = 0x20000;
1689 shdr.sh_offset = 0xf000;
1690 shdr.sh_size = 0x1000;
1691 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +00001692
1693 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1694 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1695
Christopher Ferris819f1312019-10-03 13:35:48 -07001696 int64_t load_bias = 0;
Florian Mayerda459e52018-11-23 16:56:17 +00001697 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001698 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001699}
1700
Christopher Ferris819f1312019-10-03 13:35:48 -07001701TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_32) {
1702 BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1703}
1704
1705TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_64) {
1706 BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1707}
1708
Florian Mayerda459e52018-11-23 16:56:17 +00001709template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1710void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1711 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1712
1713 uint64_t offset = 0x2000;
1714
1715 Ehdr ehdr = {};
1716 ehdr.e_shoff = offset;
1717 ehdr.e_shnum = 3;
1718 ehdr.e_shentsize = sizeof(Shdr);
1719 ehdr.e_shstrndx = 2;
1720 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1721
1722 offset += ehdr.e_shentsize;
1723
1724 char note_section[128];
1725 Nhdr note_header = {};
1726 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001727 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001728 note_header.n_type = NT_GNU_BUILD_ID;
1729 memcpy(&note_section, &note_header, sizeof(note_header));
1730 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001731 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001732 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1733 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001734 // This part of the note does not contain any trailing '\0'.
1735 memcpy(&note_section[note_offset], "BUILDID", 7);
Florian Mayerda459e52018-11-23 16:56:17 +00001736
1737 Shdr shdr = {};
1738 shdr.sh_type = SHT_NOTE;
1739 shdr.sh_name = 0x500;
1740 shdr.sh_offset = 0xb000;
1741 shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1742 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1743 offset += ehdr.e_shentsize;
1744
1745 // The string data for section header names.
1746 memset(&shdr, 0, sizeof(shdr));
1747 shdr.sh_type = SHT_STRTAB;
1748 shdr.sh_name = 0x20000;
1749 shdr.sh_offset = 0xf000;
1750 shdr.sh_size = 0x1000;
1751 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +00001752
1753 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1754 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1755
Christopher Ferris819f1312019-10-03 13:35:48 -07001756 int64_t load_bias = 0;
Florian Mayerda459e52018-11-23 16:56:17 +00001757 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001758 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001759}
1760
Christopher Ferris819f1312019-10-03 13:35:48 -07001761TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_32) {
1762 BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1763}
1764
1765TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_64) {
1766 BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1767}
1768
Florian Mayerda459e52018-11-23 16:56:17 +00001769template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
1770void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1771 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1772
1773 uint64_t offset = 0x2000;
1774
1775 Ehdr ehdr = {};
1776 ehdr.e_shoff = offset;
1777 ehdr.e_shnum = 3;
1778 ehdr.e_shentsize = sizeof(Shdr);
1779 ehdr.e_shstrndx = 2;
1780 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1781
1782 offset += ehdr.e_shentsize;
1783
1784 char note_section[128];
1785 Nhdr note_header = {};
1786 note_header.n_namesz = 4; // "GNU"
Christopher Ferris1760b452019-04-03 14:14:30 -07001787 note_header.n_descsz = 7; // "BUILDID"
Florian Mayerda459e52018-11-23 16:56:17 +00001788 note_header.n_type = NT_GNU_BUILD_ID;
1789 memcpy(&note_section, &note_header, sizeof(note_header));
1790 size_t note_offset = sizeof(note_header);
Christopher Ferris1760b452019-04-03 14:14:30 -07001791 // The note information contains the GNU and trailing '\0'.
Florian Mayerda459e52018-11-23 16:56:17 +00001792 memcpy(&note_section[note_offset], "GNU", sizeof("GNU"));
1793 note_offset += sizeof("GNU");
Christopher Ferris1760b452019-04-03 14:14:30 -07001794 // This part of the note does not contain any trailing '\0'.
1795 memcpy(&note_section[note_offset], "BUILDID", 7);
Florian Mayerda459e52018-11-23 16:56:17 +00001796
1797 Shdr shdr = {};
1798 shdr.sh_type = SHT_NOTE;
1799 shdr.sh_name = 0x500;
1800 shdr.sh_offset = 0xb000;
1801 shdr.sh_size = sizeof(note_header) - 1;
1802 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1803 offset += ehdr.e_shentsize;
1804
1805 // The string data for section header names.
1806 memset(&shdr, 0, sizeof(shdr));
1807 shdr.sh_type = SHT_STRTAB;
1808 shdr.sh_name = 0x20000;
1809 shdr.sh_offset = 0xf000;
1810 shdr.sh_size = 0x1000;
1811 memory_.SetMemory(offset, &shdr, sizeof(shdr));
Florian Mayerda459e52018-11-23 16:56:17 +00001812
1813 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1814 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1815
Christopher Ferris819f1312019-10-03 13:35:48 -07001816 int64_t load_bias = 0;
Florian Mayerda459e52018-11-23 16:56:17 +00001817 ASSERT_TRUE(elf->Init(&load_bias));
Christopher Ferrisbf373ed2019-01-16 17:23:39 -08001818 ASSERT_EQ("", elf->GetBuildID());
Florian Mayerda459e52018-11-23 16:56:17 +00001819}
1820
Christopher Ferris819f1312019-10-03 13:35:48 -07001821TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_32) {
Florian Mayerda459e52018-11-23 16:56:17 +00001822 BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1823}
1824
Christopher Ferris819f1312019-10-03 13:35:48 -07001825TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_64) {
Florian Mayerda459e52018-11-23 16:56:17 +00001826 BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1827}
1828
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001829template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
Christopher Ferris819f1312019-10-03 13:35:48 -07001830void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(int64_t load_bias) {
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001831 Ehdr ehdr = {};
1832 ehdr.e_phoff = 0x100;
1833 ehdr.e_phnum = 2;
1834 ehdr.e_phentsize = sizeof(Phdr);
1835 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1836
1837 Phdr phdr = {};
1838 phdr.p_type = PT_LOAD;
1839 phdr.p_offset = 0;
1840 phdr.p_vaddr = load_bias;
1841 phdr.p_memsz = 0x10000;
1842 phdr.p_flags = PF_R | PF_X;
1843 phdr.p_align = 0x1000;
1844 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1845
1846 memset(&phdr, 0, sizeof(phdr));
1847 phdr.p_type = PT_LOAD;
1848 phdr.p_offset = 0x1000;
1849 phdr.p_memsz = 0x2000;
1850 phdr.p_flags = PF_R | PF_X;
1851 phdr.p_align = 0x1000;
1852 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1853
Christopher Ferris819f1312019-10-03 13:35:48 -07001854 int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001855 ASSERT_EQ(load_bias, static_load_bias);
1856
1857 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
Christopher Ferris819f1312019-10-03 13:35:48 -07001858 int64_t init_load_bias = 0;
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001859 ASSERT_TRUE(elf->Init(&init_load_bias));
1860 ASSERT_EQ(init_load_bias, static_load_bias);
1861}
1862
1863TEST_F(ElfInterfaceTest, get_load_bias_zero_32) {
1864 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0);
1865}
1866
1867TEST_F(ElfInterfaceTest, get_load_bias_zero_64) {
1868 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0);
1869}
1870
1871TEST_F(ElfInterfaceTest, get_load_bias_non_zero_32) {
1872 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000);
1873}
1874
1875TEST_F(ElfInterfaceTest, get_load_bias_non_zero_64) {
1876 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000);
1877}
1878
1879template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
1880void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr,
Christopher Ferris819f1312019-10-03 13:35:48 -07001881 int64_t load_bias) {
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001882 Ehdr ehdr = {};
1883 ehdr.e_phoff = 0x100;
1884 ehdr.e_phnum = 3;
1885 ehdr.e_phentsize = sizeof(Phdr);
1886 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1887
1888 Phdr phdr = {};
1889 phdr.p_type = PT_LOAD;
1890 phdr.p_memsz = 0x10000;
1891 phdr.p_flags = PF_R;
1892 phdr.p_align = 0x1000;
1893 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1894
1895 memset(&phdr, 0, sizeof(phdr));
1896 phdr.p_type = PT_LOAD;
1897 phdr.p_offset = offset;
1898 phdr.p_vaddr = vaddr;
1899 phdr.p_memsz = 0x2000;
1900 phdr.p_flags = PF_R | PF_X;
1901 phdr.p_align = 0x1000;
1902 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1903
1904 // Second executable load should be ignored for load bias computation.
1905 memset(&phdr, 0, sizeof(phdr));
1906 phdr.p_type = PT_LOAD;
1907 phdr.p_offset = 0x1234;
1908 phdr.p_vaddr = 0x2000;
1909 phdr.p_memsz = 0x2000;
1910 phdr.p_flags = PF_R | PF_X;
1911 phdr.p_align = 0x1000;
1912 memory_.SetMemory(0x200 + sizeof(phdr), &phdr, sizeof(phdr));
1913
Christopher Ferris819f1312019-10-03 13:35:48 -07001914 int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001915 ASSERT_EQ(load_bias, static_load_bias);
1916
1917 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
Christopher Ferris819f1312019-10-03 13:35:48 -07001918 int64_t init_load_bias = 0;
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001919 ASSERT_TRUE(elf->Init(&init_load_bias));
1920 ASSERT_EQ(init_load_bias, static_load_bias);
1921}
1922
1923TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_32) {
1924 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x1000, 0);
1925}
1926
1927TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_64) {
1928 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x1000, 0);
1929}
1930
Christopher Ferris819f1312019-10-03 13:35:48 -07001931TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_32) {
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001932 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x4000, 0x3000);
1933}
1934
Christopher Ferris819f1312019-10-03 13:35:48 -07001935TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_64) {
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001936 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x4000, 0x3000);
1937}
1938
Christopher Ferris819f1312019-10-03 13:35:48 -07001939TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_32) {
1940 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, -0x4000);
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001941}
1942
Christopher Ferris819f1312019-10-03 13:35:48 -07001943TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_64) {
1944 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, -0x4000);
Christopher Ferris6c8ac562019-10-02 17:41:16 -07001945}
1946
Christopher Ferrisd226a512017-07-14 10:37:19 -07001947} // namespace unwindstack