1 /*
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 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25
26 #include <unwindstack/Elf.h>
27 #include <unwindstack/MapInfo.h>
28 #include <unwindstack/RegsArm.h>
29 #include <unwindstack/SharedString.h>
30
31 #include "ElfFake.h"
32 #include "ElfTestUtils.h"
33 #include "LogFake.h"
34 #include "utils/MemoryFake.h"
35
36 #if !defined(PT_ARM_EXIDX)
37 #define PT_ARM_EXIDX 0x70000001
38 #endif
39
40 namespace unwindstack {
41
42 class ElfTest : public ::testing::Test {
43 protected:
SetUp()44 void SetUp() override {
45 memory_ = new MemoryFake;
46 }
47
InitElf32(uint32_t machine_type)48 void InitElf32(uint32_t machine_type) {
49 Elf32_Ehdr ehdr;
50 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, machine_type);
51
52 ehdr.e_phoff = 0x100;
53 ehdr.e_ehsize = sizeof(ehdr);
54 ehdr.e_phentsize = sizeof(Elf32_Phdr);
55 ehdr.e_phnum = 1;
56 ehdr.e_shentsize = sizeof(Elf32_Shdr);
57 if (machine_type == EM_ARM) {
58 ehdr.e_flags = 0x5000200;
59 ehdr.e_phnum = 2;
60 }
61 memory_->SetMemory(0, &ehdr, sizeof(ehdr));
62
63 Elf32_Phdr phdr;
64 memset(&phdr, 0, sizeof(phdr));
65 phdr.p_type = PT_LOAD;
66 phdr.p_filesz = 0x10000;
67 phdr.p_memsz = 0x10000;
68 phdr.p_flags = PF_R | PF_X;
69 phdr.p_align = 0x1000;
70 memory_->SetMemory(0x100, &phdr, sizeof(phdr));
71
72 if (machine_type == EM_ARM) {
73 memset(&phdr, 0, sizeof(phdr));
74 phdr.p_type = PT_ARM_EXIDX;
75 phdr.p_offset = 0x30000;
76 phdr.p_vaddr = 0x30000;
77 phdr.p_paddr = 0x30000;
78 phdr.p_filesz = 16;
79 phdr.p_memsz = 16;
80 phdr.p_flags = PF_R;
81 phdr.p_align = 0x4;
82 memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
83 }
84 }
85
InitElf64(uint32_t machine_type)86 void InitElf64(uint32_t machine_type) {
87 Elf64_Ehdr ehdr;
88 TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, machine_type);
89
90 ehdr.e_phoff = 0x100;
91 ehdr.e_flags = 0x5000200;
92 ehdr.e_ehsize = sizeof(ehdr);
93 ehdr.e_phentsize = sizeof(Elf64_Phdr);
94 ehdr.e_phnum = 1;
95 ehdr.e_shentsize = sizeof(Elf64_Shdr);
96 memory_->SetMemory(0, &ehdr, sizeof(ehdr));
97
98 Elf64_Phdr phdr;
99 memset(&phdr, 0, sizeof(phdr));
100 phdr.p_type = PT_LOAD;
101 phdr.p_filesz = 0x10000;
102 phdr.p_memsz = 0x10000;
103 phdr.p_flags = PF_R | PF_X;
104 phdr.p_align = 0x1000;
105 memory_->SetMemory(0x100, &phdr, sizeof(phdr));
106 }
107
108 void VerifyStepIfSignalHandler(uint64_t load_bias);
109
110 MemoryFake* memory_;
111 };
112
TEST_F(ElfTest,invalid_memory)113 TEST_F(ElfTest, invalid_memory) {
114 Elf elf(memory_);
115
116 ASSERT_FALSE(elf.Init());
117 ASSERT_FALSE(elf.valid());
118 }
119
TEST_F(ElfTest,elf_invalid)120 TEST_F(ElfTest, elf_invalid) {
121 Elf elf(memory_);
122
123 InitElf32(EM_386);
124
125 // Corrupt the ELF signature.
126 memory_->SetData32(0, 0x7f000000);
127
128 ASSERT_FALSE(elf.Init());
129 ASSERT_FALSE(elf.valid());
130 ASSERT_TRUE(elf.interface() == nullptr);
131
132 ASSERT_EQ("", elf.GetSoname());
133
134 SharedString name;
135 uint64_t func_offset;
136 ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset));
137
138 ASSERT_FALSE(elf.StepIfSignalHandler(0, nullptr, nullptr));
139 EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode());
140
141 bool finished;
142 bool is_signal_frame;
143 ASSERT_FALSE(elf.Step(0, nullptr, nullptr, &finished, &is_signal_frame));
144 EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode());
145 }
146
TEST_F(ElfTest,elf_invalid_check_error_values)147 TEST_F(ElfTest, elf_invalid_check_error_values) {
148 ElfFake elf(memory_);
149 elf.FakeSetValid(false);
150
151 EXPECT_EQ(ERROR_INVALID_ELF, elf.GetLastErrorCode());
152 EXPECT_EQ(0U, elf.GetLastErrorAddress());
153
154 ErrorData error = {};
155 elf.GetLastError(&error);
156 EXPECT_EQ(ERROR_INVALID_ELF, error.code);
157 EXPECT_EQ(0U, error.address);
158
159 error.code = ERROR_MEMORY_INVALID;
160 error.address = 0x100;
161 elf.GetLastError(&error);
162 EXPECT_EQ(ERROR_INVALID_ELF, error.code);
163 EXPECT_EQ(0U, error.address);
164 }
165
TEST_F(ElfTest,elf32_invalid_machine)166 TEST_F(ElfTest, elf32_invalid_machine) {
167 Elf elf(memory_);
168
169 InitElf32(EM_PPC);
170
171 ResetLogs();
172 ASSERT_FALSE(elf.Init());
173
174 ASSERT_EQ("", GetFakeLogBuf());
175 ASSERT_EQ("", GetFakeLogPrint());
176 }
177
TEST_F(ElfTest,elf64_invalid_machine)178 TEST_F(ElfTest, elf64_invalid_machine) {
179 Elf elf(memory_);
180
181 InitElf64(EM_PPC64);
182
183 ResetLogs();
184 ASSERT_FALSE(elf.Init());
185
186 ASSERT_EQ("", GetFakeLogBuf());
187 ASSERT_EQ("", GetFakeLogPrint());
188 }
189
TEST_F(ElfTest,elf_arm)190 TEST_F(ElfTest, elf_arm) {
191 Elf elf(memory_);
192
193 InitElf32(EM_ARM);
194
195 ASSERT_TRUE(elf.Init());
196 ASSERT_TRUE(elf.valid());
197 ASSERT_EQ(static_cast<uint32_t>(EM_ARM), elf.machine_type());
198 ASSERT_EQ(ELFCLASS32, elf.class_type());
199 ASSERT_TRUE(elf.interface() != nullptr);
200 }
201
TEST_F(ElfTest,elf_mips)202 TEST_F(ElfTest, elf_mips) {
203 Elf elf(memory_);
204
205 InitElf32(EM_MIPS);
206
207 ASSERT_TRUE(elf.Init());
208 ASSERT_TRUE(elf.valid());
209 ASSERT_EQ(static_cast<uint32_t>(EM_MIPS), elf.machine_type());
210 ASSERT_EQ(ELFCLASS32, elf.class_type());
211 ASSERT_TRUE(elf.interface() != nullptr);
212 }
213
TEST_F(ElfTest,elf_x86)214 TEST_F(ElfTest, elf_x86) {
215 Elf elf(memory_);
216
217 InitElf32(EM_386);
218
219 ASSERT_TRUE(elf.Init());
220 ASSERT_TRUE(elf.valid());
221 ASSERT_EQ(static_cast<uint32_t>(EM_386), elf.machine_type());
222 ASSERT_EQ(ELFCLASS32, elf.class_type());
223 ASSERT_TRUE(elf.interface() != nullptr);
224 }
225
TEST_F(ElfTest,elf_arm64)226 TEST_F(ElfTest, elf_arm64) {
227 Elf elf(memory_);
228
229 InitElf64(EM_AARCH64);
230
231 ASSERT_TRUE(elf.Init());
232 ASSERT_TRUE(elf.valid());
233 ASSERT_EQ(static_cast<uint32_t>(EM_AARCH64), elf.machine_type());
234 ASSERT_EQ(ELFCLASS64, elf.class_type());
235 ASSERT_TRUE(elf.interface() != nullptr);
236 }
237
TEST_F(ElfTest,elf_riscv64)238 TEST_F(ElfTest, elf_riscv64) {
239 Elf elf(memory_);
240
241 InitElf64(EM_RISCV);
242
243 ASSERT_TRUE(elf.Init());
244 ASSERT_TRUE(elf.valid());
245 ASSERT_EQ(static_cast<uint32_t>(EM_RISCV), elf.machine_type());
246 ASSERT_EQ(ELFCLASS64, elf.class_type());
247 ASSERT_TRUE(elf.interface() != nullptr);
248 }
249
TEST_F(ElfTest,elf_x86_64)250 TEST_F(ElfTest, elf_x86_64) {
251 Elf elf(memory_);
252
253 InitElf64(EM_X86_64);
254
255 ASSERT_TRUE(elf.Init());
256 ASSERT_TRUE(elf.valid());
257 ASSERT_EQ(static_cast<uint32_t>(EM_X86_64), elf.machine_type());
258 ASSERT_EQ(ELFCLASS64, elf.class_type());
259 ASSERT_TRUE(elf.interface() != nullptr);
260 }
261
TEST_F(ElfTest,elf_mips64)262 TEST_F(ElfTest, elf_mips64) {
263 Elf elf(memory_);
264
265 InitElf64(EM_MIPS);
266
267 ASSERT_TRUE(elf.Init());
268 ASSERT_TRUE(elf.valid());
269 ASSERT_EQ(static_cast<uint32_t>(EM_MIPS), elf.machine_type());
270 ASSERT_EQ(ELFCLASS64, elf.class_type());
271 ASSERT_TRUE(elf.interface() != nullptr);
272 }
273
TEST_F(ElfTest,gnu_debugdata_init32)274 TEST_F(ElfTest, gnu_debugdata_init32) {
275 TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
276 [&](uint64_t offset, const void* ptr, size_t size) {
277 memory_->SetMemory(offset, ptr, size);
278 });
279
280 Elf elf(memory_);
281 ASSERT_TRUE(elf.Init());
282 ASSERT_TRUE(elf.interface() != nullptr);
283 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
284 EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
285 EXPECT_EQ(0x8cU, elf.interface()->gnu_debugdata_size());
286 }
287
TEST_F(ElfTest,gnu_debugdata_init64)288 TEST_F(ElfTest, gnu_debugdata_init64) {
289 TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
290 [&](uint64_t offset, const void* ptr, size_t size) {
291 memory_->SetMemory(offset, ptr, size);
292 });
293
294 Elf elf(memory_);
295 ASSERT_TRUE(elf.Init());
296 ASSERT_TRUE(elf.interface() != nullptr);
297 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
298 EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
299 EXPECT_EQ(0x90U, elf.interface()->gnu_debugdata_size());
300 }
301
TEST_F(ElfTest,rel_pc)302 TEST_F(ElfTest, rel_pc) {
303 ElfFake elf(memory_);
304
305 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
306 elf.FakeSetInterface(interface);
307
308 elf.FakeSetValid(true);
309 auto map_info = MapInfo::Create(0x1000, 0x2000, 0, 0, "");
310
311 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, map_info.get()));
312
313 elf.FakeSetValid(false);
314 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, map_info.get()));
315 }
316
VerifyStepIfSignalHandler(uint64_t load_bias)317 void ElfTest::VerifyStepIfSignalHandler(uint64_t load_bias) {
318 ElfFake elf(memory_);
319
320 RegsArm regs;
321 regs[13] = 0x50000;
322 regs[15] = 0x8000;
323
324 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
325 elf.FakeSetInterface(interface);
326 elf.FakeSetLoadBias(load_bias);
327
328 memory_->SetData32(0x3000, 0xdf0027ad);
329 MemoryFake process_memory;
330 process_memory.SetData32(0x50000, 0);
331 for (size_t i = 0; i < 16; i++) {
332 process_memory.SetData32(0x500a0 + i * sizeof(uint32_t), i);
333 }
334
335 elf.FakeSetValid(true);
336 ASSERT_TRUE(elf.StepIfSignalHandler(0x3000 + load_bias, ®s, &process_memory));
337 EXPECT_EQ(ERROR_NONE, elf.GetLastErrorCode());
338 EXPECT_EQ(15U, regs.pc());
339 EXPECT_EQ(13U, regs.sp());
340 }
341
TEST_F(ElfTest,step_in_signal_map)342 TEST_F(ElfTest, step_in_signal_map) {
343 VerifyStepIfSignalHandler(0);
344 }
345
TEST_F(ElfTest,step_in_signal_map_non_zero_load_bias)346 TEST_F(ElfTest, step_in_signal_map_non_zero_load_bias) {
347 VerifyStepIfSignalHandler(0x1000);
348 }
349
350 class ElfInterfaceMock : public ElfInterface {
351 public:
ElfInterfaceMock(Memory * memory)352 ElfInterfaceMock(Memory* memory) : ElfInterface(memory) {}
353 virtual ~ElfInterfaceMock() = default;
354
Init(int64_t *)355 bool Init(int64_t*) override { return false; }
InitHeaders()356 void InitHeaders() override {}
GetSoname()357 std::string GetSoname() override { return ""; }
GetFunctionName(uint64_t,SharedString *,uint64_t *)358 bool GetFunctionName(uint64_t, SharedString*, uint64_t*) override { return false; }
GetBuildID()359 std::string GetBuildID() override { return ""; }
360
361 MOCK_METHOD(bool, Step, (uint64_t, Regs*, Memory*, bool*, bool*), (override));
362 MOCK_METHOD(bool, GetGlobalVariable, (const std::string&, uint64_t*), (override));
363 MOCK_METHOD(bool, IsValidPc, (uint64_t), (override));
364
MockSetDataOffset(uint64_t offset)365 void MockSetDataOffset(uint64_t offset) { data_offset_ = offset; }
MockSetDataVaddrStart(uint64_t vaddr)366 void MockSetDataVaddrStart(uint64_t vaddr) { data_vaddr_start_ = vaddr; }
MockSetDataVaddrEnd(uint64_t vaddr)367 void MockSetDataVaddrEnd(uint64_t vaddr) { data_vaddr_end_ = vaddr; }
368
MockSetDynamicOffset(uint64_t offset)369 void MockSetDynamicOffset(uint64_t offset) { dynamic_offset_ = offset; }
MockSetDynamicVaddrStart(uint64_t vaddr)370 void MockSetDynamicVaddrStart(uint64_t vaddr) { dynamic_vaddr_start_ = vaddr; }
MockSetDynamicVaddrEnd(uint64_t vaddr)371 void MockSetDynamicVaddrEnd(uint64_t vaddr) { dynamic_vaddr_end_ = vaddr; }
372 };
373
TEST_F(ElfTest,step_in_interface)374 TEST_F(ElfTest, step_in_interface) {
375 ElfFake elf(memory_);
376 elf.FakeSetValid(true);
377
378 RegsArm regs;
379
380 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
381 elf.FakeSetInterface(interface);
382 MemoryFake process_memory;
383
384 bool finished;
385 bool is_signal_frame;
386 EXPECT_CALL(*interface, Step(0x1000, ®s, &process_memory, &finished, &is_signal_frame))
387 .WillOnce(::testing::Return(true));
388
389 ASSERT_TRUE(elf.Step(0x1000, ®s, &process_memory, &finished, &is_signal_frame));
390 }
391
TEST_F(ElfTest,get_global_invalid_elf)392 TEST_F(ElfTest, get_global_invalid_elf) {
393 ElfFake elf(memory_);
394 elf.FakeSetValid(false);
395
396 std::string global("something");
397 uint64_t offset;
398 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
399 }
400
TEST_F(ElfTest,get_global_valid_not_in_interface)401 TEST_F(ElfTest, get_global_valid_not_in_interface) {
402 ElfFake elf(memory_);
403 elf.FakeSetValid(true);
404
405 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
406 elf.FakeSetInterface(interface);
407
408 std::string global("something");
409 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
410 .WillOnce(::testing::Return(false));
411
412 uint64_t offset;
413 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
414 }
415
TEST_F(ElfTest,get_global_vaddr_in_no_sections)416 TEST_F(ElfTest, get_global_vaddr_in_no_sections) {
417 ElfFake elf(memory_);
418 elf.FakeSetValid(true);
419
420 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
421 elf.FakeSetInterface(interface);
422
423 std::string global("something");
424 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
425 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x300), ::testing::Return(true)));
426
427 uint64_t offset;
428 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
429 }
430
TEST_F(ElfTest,get_global_vaddr_in_data_section)431 TEST_F(ElfTest, get_global_vaddr_in_data_section) {
432 ElfFake elf(memory_);
433 elf.FakeSetValid(true);
434
435 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
436 elf.FakeSetInterface(interface);
437 interface->MockSetDataVaddrStart(0x500);
438 interface->MockSetDataVaddrEnd(0x600);
439 interface->MockSetDataOffset(0xa000);
440
441 std::string global("something");
442 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
443 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x580), ::testing::Return(true)));
444
445 uint64_t offset;
446 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
447 EXPECT_EQ(0xa080U, offset);
448 }
449
TEST_F(ElfTest,get_global_vaddr_in_dynamic_section)450 TEST_F(ElfTest, get_global_vaddr_in_dynamic_section) {
451 ElfFake elf(memory_);
452 elf.FakeSetValid(true);
453
454 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
455 elf.FakeSetInterface(interface);
456 interface->MockSetDataVaddrStart(0x500);
457 interface->MockSetDataVaddrEnd(0x600);
458 interface->MockSetDataOffset(0xa000);
459
460 interface->MockSetDynamicVaddrStart(0x800);
461 interface->MockSetDynamicVaddrEnd(0x900);
462 interface->MockSetDynamicOffset(0xc000);
463
464 std::string global("something");
465 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
466 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x880), ::testing::Return(true)));
467
468 uint64_t offset;
469 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
470 EXPECT_EQ(0xc080U, offset);
471 }
472
TEST_F(ElfTest,get_global_vaddr_with_tagged_pointer)473 TEST_F(ElfTest, get_global_vaddr_with_tagged_pointer) {
474 ElfFake elf(memory_);
475 elf.FakeSetValid(true);
476 elf.FakeSetArch(ARCH_ARM64);
477
478 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
479 elf.FakeSetInterface(interface);
480 interface->MockSetDataVaddrStart(0x500);
481 interface->MockSetDataVaddrEnd(0x600);
482 interface->MockSetDataOffset(0xa000);
483
484 std::string global("something");
485 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
486 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
487 ::testing::Return(true)));
488
489 uint64_t offset;
490 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
491 EXPECT_EQ(0xa080U, offset);
492 }
493
TEST_F(ElfTest,get_global_vaddr_without_tagged_pointer)494 TEST_F(ElfTest, get_global_vaddr_without_tagged_pointer) {
495 ElfFake elf(memory_);
496 elf.FakeSetValid(true);
497 elf.FakeSetArch(ARCH_X86_64);
498
499 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
500 elf.FakeSetInterface(interface);
501 interface->MockSetDataVaddrStart(0x8800000000000500);
502 interface->MockSetDataVaddrEnd(0x8800000000000600);
503 interface->MockSetDataOffset(0x880000000000a000);
504
505 std::string global("something");
506 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
507 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
508 ::testing::Return(true)));
509
510 uint64_t offset;
511 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
512 EXPECT_EQ(0x880000000000a080U, offset);
513 }
514
TEST_F(ElfTest,is_valid_pc_elf_invalid)515 TEST_F(ElfTest, is_valid_pc_elf_invalid) {
516 ElfFake elf(memory_);
517 elf.FakeSetValid(false);
518
519 EXPECT_FALSE(elf.IsValidPc(0x100));
520 EXPECT_FALSE(elf.IsValidPc(0x200));
521 }
522
TEST_F(ElfTest,is_valid_pc_interface)523 TEST_F(ElfTest, is_valid_pc_interface) {
524 ElfFake elf(memory_);
525 elf.FakeSetValid(true);
526
527 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
528 elf.FakeSetInterface(interface);
529
530 EXPECT_CALL(*interface, IsValidPc(0x1500)).WillOnce(::testing::Return(true));
531
532 EXPECT_TRUE(elf.IsValidPc(0x1500));
533 }
534
TEST_F(ElfTest,is_valid_pc_from_gnu_debugdata)535 TEST_F(ElfTest, is_valid_pc_from_gnu_debugdata) {
536 ElfFake elf(memory_);
537 elf.FakeSetValid(true);
538
539 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
540 elf.FakeSetInterface(interface);
541 ElfInterfaceMock* gnu_interface = new ElfInterfaceMock(memory_);
542 elf.FakeSetGnuDebugdataInterface(gnu_interface);
543
544 EXPECT_CALL(*interface, IsValidPc(0x1500)).WillOnce(::testing::Return(false));
545 EXPECT_CALL(*gnu_interface, IsValidPc(0x1500)).WillOnce(::testing::Return(true));
546
547 EXPECT_TRUE(elf.IsValidPc(0x1500));
548 }
549
TEST_F(ElfTest,error_code_valid)550 TEST_F(ElfTest, error_code_valid) {
551 ElfFake elf(memory_);
552 elf.FakeSetValid(true);
553 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
554 elf.FakeSetInterface(interface);
555 interface->FakeSetErrorCode(ERROR_MEMORY_INVALID);
556 interface->FakeSetErrorAddress(0x1000);
557
558 ErrorData error{ERROR_NONE, 0};
559 elf.GetLastError(&error);
560 EXPECT_EQ(ERROR_MEMORY_INVALID, error.code);
561 EXPECT_EQ(0x1000U, error.address);
562 EXPECT_EQ(ERROR_MEMORY_INVALID, elf.GetLastErrorCode());
563 EXPECT_EQ(0x1000U, elf.GetLastErrorAddress());
564 }
565
TEST(ElfBuildIdTest,get_printable_build_id_empty)566 TEST(ElfBuildIdTest, get_printable_build_id_empty) {
567 std::string empty;
568 ASSERT_EQ("", Elf::GetPrintableBuildID(empty));
569 }
570
TEST(ElfBuildIdTest,get_printable_build_id_check)571 TEST(ElfBuildIdTest, get_printable_build_id_check) {
572 std::string empty = {'\xff', '\x45', '\x40', '\x0f'};
573 ASSERT_EQ("ff45400f", Elf::GetPrintableBuildID(empty));
574 }
575
576 } // namespace unwindstack
577