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 "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("4 unwind 32 bit elf that is neither arm nor x86 nor mips: e_machine = 20\n\n",
176 GetFakeLogPrint());
177 }
178
TEST_F(ElfTest,elf64_invalid_machine)179 TEST_F(ElfTest, elf64_invalid_machine) {
180 Elf elf(memory_);
181
182 InitElf64(EM_PPC64);
183
184 ResetLogs();
185 ASSERT_FALSE(elf.Init());
186
187 ASSERT_EQ("", GetFakeLogBuf());
188 ASSERT_EQ("4 unwind 64 bit elf that is neither aarch64 nor x86_64 nor mips64: e_machine = 21\n\n",
189 GetFakeLogPrint());
190 }
191
TEST_F(ElfTest,elf_arm)192 TEST_F(ElfTest, elf_arm) {
193 Elf elf(memory_);
194
195 InitElf32(EM_ARM);
196
197 ASSERT_TRUE(elf.Init());
198 ASSERT_TRUE(elf.valid());
199 ASSERT_EQ(static_cast<uint32_t>(EM_ARM), elf.machine_type());
200 ASSERT_EQ(ELFCLASS32, elf.class_type());
201 ASSERT_TRUE(elf.interface() != nullptr);
202 }
203
TEST_F(ElfTest,elf_mips)204 TEST_F(ElfTest, elf_mips) {
205 Elf elf(memory_);
206
207 InitElf32(EM_MIPS);
208
209 ASSERT_TRUE(elf.Init());
210 ASSERT_TRUE(elf.valid());
211 ASSERT_EQ(static_cast<uint32_t>(EM_MIPS), elf.machine_type());
212 ASSERT_EQ(ELFCLASS32, elf.class_type());
213 ASSERT_TRUE(elf.interface() != nullptr);
214 }
215
TEST_F(ElfTest,elf_x86)216 TEST_F(ElfTest, elf_x86) {
217 Elf elf(memory_);
218
219 InitElf32(EM_386);
220
221 ASSERT_TRUE(elf.Init());
222 ASSERT_TRUE(elf.valid());
223 ASSERT_EQ(static_cast<uint32_t>(EM_386), elf.machine_type());
224 ASSERT_EQ(ELFCLASS32, elf.class_type());
225 ASSERT_TRUE(elf.interface() != nullptr);
226 }
227
TEST_F(ElfTest,elf_arm64)228 TEST_F(ElfTest, elf_arm64) {
229 Elf elf(memory_);
230
231 InitElf64(EM_AARCH64);
232
233 ASSERT_TRUE(elf.Init());
234 ASSERT_TRUE(elf.valid());
235 ASSERT_EQ(static_cast<uint32_t>(EM_AARCH64), elf.machine_type());
236 ASSERT_EQ(ELFCLASS64, elf.class_type());
237 ASSERT_TRUE(elf.interface() != nullptr);
238 }
239
TEST_F(ElfTest,elf_x86_64)240 TEST_F(ElfTest, elf_x86_64) {
241 Elf elf(memory_);
242
243 InitElf64(EM_X86_64);
244
245 ASSERT_TRUE(elf.Init());
246 ASSERT_TRUE(elf.valid());
247 ASSERT_EQ(static_cast<uint32_t>(EM_X86_64), elf.machine_type());
248 ASSERT_EQ(ELFCLASS64, elf.class_type());
249 ASSERT_TRUE(elf.interface() != nullptr);
250 }
251
TEST_F(ElfTest,elf_mips64)252 TEST_F(ElfTest, elf_mips64) {
253 Elf elf(memory_);
254
255 InitElf64(EM_MIPS);
256
257 ASSERT_TRUE(elf.Init());
258 ASSERT_TRUE(elf.valid());
259 ASSERT_EQ(static_cast<uint32_t>(EM_MIPS), elf.machine_type());
260 ASSERT_EQ(ELFCLASS64, elf.class_type());
261 ASSERT_TRUE(elf.interface() != nullptr);
262 }
263
TEST_F(ElfTest,gnu_debugdata_init32)264 TEST_F(ElfTest, gnu_debugdata_init32) {
265 TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
266 [&](uint64_t offset, const void* ptr, size_t size) {
267 memory_->SetMemory(offset, ptr, size);
268 });
269
270 Elf elf(memory_);
271 ASSERT_TRUE(elf.Init());
272 ASSERT_TRUE(elf.interface() != nullptr);
273 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
274 EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
275 EXPECT_EQ(0x8cU, elf.interface()->gnu_debugdata_size());
276 }
277
TEST_F(ElfTest,gnu_debugdata_init64)278 TEST_F(ElfTest, gnu_debugdata_init64) {
279 TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
280 [&](uint64_t offset, const void* ptr, size_t size) {
281 memory_->SetMemory(offset, ptr, size);
282 });
283
284 Elf elf(memory_);
285 ASSERT_TRUE(elf.Init());
286 ASSERT_TRUE(elf.interface() != nullptr);
287 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
288 EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
289 EXPECT_EQ(0x90U, elf.interface()->gnu_debugdata_size());
290 }
291
TEST_F(ElfTest,rel_pc)292 TEST_F(ElfTest, rel_pc) {
293 ElfFake elf(memory_);
294
295 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
296 elf.FakeSetInterface(interface);
297
298 elf.FakeSetValid(true);
299 MapInfo map_info(nullptr, nullptr, 0x1000, 0x2000, 0, 0, "");
300
301 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info));
302
303 elf.FakeSetValid(false);
304 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info));
305 }
306
VerifyStepIfSignalHandler(uint64_t load_bias)307 void ElfTest::VerifyStepIfSignalHandler(uint64_t load_bias) {
308 ElfFake elf(memory_);
309
310 RegsArm regs;
311 regs[13] = 0x50000;
312 regs[15] = 0x8000;
313
314 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
315 elf.FakeSetInterface(interface);
316 elf.FakeSetLoadBias(load_bias);
317
318 memory_->SetData32(0x3000, 0xdf0027ad);
319 MemoryFake process_memory;
320 process_memory.SetData32(0x50000, 0);
321 for (size_t i = 0; i < 16; i++) {
322 process_memory.SetData32(0x500a0 + i * sizeof(uint32_t), i);
323 }
324
325 elf.FakeSetValid(true);
326 ASSERT_TRUE(elf.StepIfSignalHandler(0x3000 + load_bias, ®s, &process_memory));
327 EXPECT_EQ(ERROR_NONE, elf.GetLastErrorCode());
328 EXPECT_EQ(15U, regs.pc());
329 EXPECT_EQ(13U, regs.sp());
330 }
331
TEST_F(ElfTest,step_in_signal_map)332 TEST_F(ElfTest, step_in_signal_map) {
333 VerifyStepIfSignalHandler(0);
334 }
335
TEST_F(ElfTest,step_in_signal_map_non_zero_load_bias)336 TEST_F(ElfTest, step_in_signal_map_non_zero_load_bias) {
337 VerifyStepIfSignalHandler(0x1000);
338 }
339
340 class ElfInterfaceMock : public ElfInterface {
341 public:
ElfInterfaceMock(Memory * memory)342 ElfInterfaceMock(Memory* memory) : ElfInterface(memory) {}
343 virtual ~ElfInterfaceMock() = default;
344
Init(int64_t *)345 bool Init(int64_t*) override { return false; }
InitHeaders()346 void InitHeaders() override {}
GetSoname()347 std::string GetSoname() override { return ""; }
GetFunctionName(uint64_t,SharedString *,uint64_t *)348 bool GetFunctionName(uint64_t, SharedString*, uint64_t*) override { return false; }
GetBuildID()349 std::string GetBuildID() override { return ""; }
350
351 MOCK_METHOD(bool, Step, (uint64_t, Regs*, Memory*, bool*, bool*), (override));
352 MOCK_METHOD(bool, GetGlobalVariable, (const std::string&, uint64_t*), (override));
353 MOCK_METHOD(bool, IsValidPc, (uint64_t), (override));
354
MockSetDataOffset(uint64_t offset)355 void MockSetDataOffset(uint64_t offset) { data_offset_ = offset; }
MockSetDataVaddrStart(uint64_t vaddr)356 void MockSetDataVaddrStart(uint64_t vaddr) { data_vaddr_start_ = vaddr; }
MockSetDataVaddrEnd(uint64_t vaddr)357 void MockSetDataVaddrEnd(uint64_t vaddr) { data_vaddr_end_ = vaddr; }
358
MockSetDynamicOffset(uint64_t offset)359 void MockSetDynamicOffset(uint64_t offset) { dynamic_offset_ = offset; }
MockSetDynamicVaddrStart(uint64_t vaddr)360 void MockSetDynamicVaddrStart(uint64_t vaddr) { dynamic_vaddr_start_ = vaddr; }
MockSetDynamicVaddrEnd(uint64_t vaddr)361 void MockSetDynamicVaddrEnd(uint64_t vaddr) { dynamic_vaddr_end_ = vaddr; }
362 };
363
TEST_F(ElfTest,step_in_interface)364 TEST_F(ElfTest, step_in_interface) {
365 ElfFake elf(memory_);
366 elf.FakeSetValid(true);
367
368 RegsArm regs;
369
370 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
371 elf.FakeSetInterface(interface);
372 MemoryFake process_memory;
373
374 bool finished;
375 bool is_signal_frame;
376 EXPECT_CALL(*interface, Step(0x1000, ®s, &process_memory, &finished, &is_signal_frame))
377 .WillOnce(::testing::Return(true));
378
379 ASSERT_TRUE(elf.Step(0x1000, ®s, &process_memory, &finished, &is_signal_frame));
380 }
381
TEST_F(ElfTest,get_global_invalid_elf)382 TEST_F(ElfTest, get_global_invalid_elf) {
383 ElfFake elf(memory_);
384 elf.FakeSetValid(false);
385
386 std::string global("something");
387 uint64_t offset;
388 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
389 }
390
TEST_F(ElfTest,get_global_valid_not_in_interface)391 TEST_F(ElfTest, get_global_valid_not_in_interface) {
392 ElfFake elf(memory_);
393 elf.FakeSetValid(true);
394
395 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
396 elf.FakeSetInterface(interface);
397
398 std::string global("something");
399 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
400 .WillOnce(::testing::Return(false));
401
402 uint64_t offset;
403 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
404 }
405
TEST_F(ElfTest,get_global_vaddr_in_no_sections)406 TEST_F(ElfTest, get_global_vaddr_in_no_sections) {
407 ElfFake elf(memory_);
408 elf.FakeSetValid(true);
409
410 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
411 elf.FakeSetInterface(interface);
412
413 std::string global("something");
414 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
415 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x300), ::testing::Return(true)));
416
417 uint64_t offset;
418 ASSERT_FALSE(elf.GetGlobalVariableOffset(global, &offset));
419 }
420
TEST_F(ElfTest,get_global_vaddr_in_data_section)421 TEST_F(ElfTest, get_global_vaddr_in_data_section) {
422 ElfFake elf(memory_);
423 elf.FakeSetValid(true);
424
425 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
426 elf.FakeSetInterface(interface);
427 interface->MockSetDataVaddrStart(0x500);
428 interface->MockSetDataVaddrEnd(0x600);
429 interface->MockSetDataOffset(0xa000);
430
431 std::string global("something");
432 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
433 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x580), ::testing::Return(true)));
434
435 uint64_t offset;
436 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
437 EXPECT_EQ(0xa080U, offset);
438 }
439
TEST_F(ElfTest,get_global_vaddr_in_dynamic_section)440 TEST_F(ElfTest, get_global_vaddr_in_dynamic_section) {
441 ElfFake elf(memory_);
442 elf.FakeSetValid(true);
443
444 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
445 elf.FakeSetInterface(interface);
446 interface->MockSetDataVaddrStart(0x500);
447 interface->MockSetDataVaddrEnd(0x600);
448 interface->MockSetDataOffset(0xa000);
449
450 interface->MockSetDynamicVaddrStart(0x800);
451 interface->MockSetDynamicVaddrEnd(0x900);
452 interface->MockSetDynamicOffset(0xc000);
453
454 std::string global("something");
455 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
456 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x880), ::testing::Return(true)));
457
458 uint64_t offset;
459 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
460 EXPECT_EQ(0xc080U, offset);
461 }
462
TEST_F(ElfTest,get_global_vaddr_with_tagged_pointer)463 TEST_F(ElfTest, get_global_vaddr_with_tagged_pointer) {
464 ElfFake elf(memory_);
465 elf.FakeSetValid(true);
466 elf.FakeSetArch(ARCH_ARM64);
467
468 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
469 elf.FakeSetInterface(interface);
470 interface->MockSetDataVaddrStart(0x500);
471 interface->MockSetDataVaddrEnd(0x600);
472 interface->MockSetDataOffset(0xa000);
473
474 std::string global("something");
475 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
476 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
477 ::testing::Return(true)));
478
479 uint64_t offset;
480 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
481 EXPECT_EQ(0xa080U, offset);
482 }
483
TEST_F(ElfTest,get_global_vaddr_without_tagged_pointer)484 TEST_F(ElfTest, get_global_vaddr_without_tagged_pointer) {
485 ElfFake elf(memory_);
486 elf.FakeSetValid(true);
487 elf.FakeSetArch(ARCH_X86_64);
488
489 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
490 elf.FakeSetInterface(interface);
491 interface->MockSetDataVaddrStart(0x8800000000000500);
492 interface->MockSetDataVaddrEnd(0x8800000000000600);
493 interface->MockSetDataOffset(0x880000000000a000);
494
495 std::string global("something");
496 EXPECT_CALL(*interface, GetGlobalVariable(global, ::testing::_))
497 .WillOnce(::testing::DoAll(::testing::SetArgPointee<1>(0x8800000000000580),
498 ::testing::Return(true)));
499
500 uint64_t offset;
501 ASSERT_TRUE(elf.GetGlobalVariableOffset(global, &offset));
502 EXPECT_EQ(0x880000000000a080U, offset);
503 }
504
TEST_F(ElfTest,is_valid_pc_elf_invalid)505 TEST_F(ElfTest, is_valid_pc_elf_invalid) {
506 ElfFake elf(memory_);
507 elf.FakeSetValid(false);
508
509 EXPECT_FALSE(elf.IsValidPc(0x100));
510 EXPECT_FALSE(elf.IsValidPc(0x200));
511 }
512
TEST_F(ElfTest,is_valid_pc_interface)513 TEST_F(ElfTest, is_valid_pc_interface) {
514 ElfFake elf(memory_);
515 elf.FakeSetValid(true);
516
517 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
518 elf.FakeSetInterface(interface);
519
520 EXPECT_CALL(*interface, IsValidPc(0x1500)).WillOnce(::testing::Return(true));
521
522 EXPECT_TRUE(elf.IsValidPc(0x1500));
523 }
524
TEST_F(ElfTest,is_valid_pc_from_gnu_debugdata)525 TEST_F(ElfTest, is_valid_pc_from_gnu_debugdata) {
526 ElfFake elf(memory_);
527 elf.FakeSetValid(true);
528
529 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_);
530 elf.FakeSetInterface(interface);
531 ElfInterfaceMock* gnu_interface = new ElfInterfaceMock(memory_);
532 elf.FakeSetGnuDebugdataInterface(gnu_interface);
533
534 EXPECT_CALL(*interface, IsValidPc(0x1500)).WillOnce(::testing::Return(false));
535 EXPECT_CALL(*gnu_interface, IsValidPc(0x1500)).WillOnce(::testing::Return(true));
536
537 EXPECT_TRUE(elf.IsValidPc(0x1500));
538 }
539
TEST_F(ElfTest,error_code_valid)540 TEST_F(ElfTest, error_code_valid) {
541 ElfFake elf(memory_);
542 elf.FakeSetValid(true);
543 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_);
544 elf.FakeSetInterface(interface);
545 interface->FakeSetErrorCode(ERROR_MEMORY_INVALID);
546 interface->FakeSetErrorAddress(0x1000);
547
548 ErrorData error{ERROR_NONE, 0};
549 elf.GetLastError(&error);
550 EXPECT_EQ(ERROR_MEMORY_INVALID, error.code);
551 EXPECT_EQ(0x1000U, error.address);
552 EXPECT_EQ(ERROR_MEMORY_INVALID, elf.GetLastErrorCode());
553 EXPECT_EQ(0x1000U, elf.GetLastErrorAddress());
554 }
555
556 } // namespace unwindstack
557