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