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/mman.h>
20*eb293b8fSAndroid Build Coastguard Worker #include <sys/stat.h>
21*eb293b8fSAndroid Build Coastguard Worker
22*eb293b8fSAndroid Build Coastguard Worker #include <memory>
23*eb293b8fSAndroid Build Coastguard Worker #include <vector>
24*eb293b8fSAndroid Build Coastguard Worker
25*eb293b8fSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
26*eb293b8fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
27*eb293b8fSAndroid Build Coastguard Worker
28*eb293b8fSAndroid Build Coastguard Worker #include <unwindstack/ElfInterface.h>
29*eb293b8fSAndroid Build Coastguard Worker
30*eb293b8fSAndroid Build Coastguard Worker #include "DwarfEncoding.h"
31*eb293b8fSAndroid Build Coastguard Worker #include "ElfInterfaceArm.h"
32*eb293b8fSAndroid Build Coastguard Worker #include "MemoryRange.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 "utils/MemoryFake.h"
37*eb293b8fSAndroid Build Coastguard Worker
38*eb293b8fSAndroid Build Coastguard Worker #if __has_feature(address_sanitizer)
39*eb293b8fSAndroid Build Coastguard Worker // There is a test that tries to allocate a large value, allow it to fail
40*eb293b8fSAndroid Build Coastguard Worker // if asan is enabled.
__asan_default_options()41*eb293b8fSAndroid Build Coastguard Worker extern "C" const char* __asan_default_options() {
42*eb293b8fSAndroid Build Coastguard Worker return "allocator_may_return_null=1";
43*eb293b8fSAndroid Build Coastguard Worker }
44*eb293b8fSAndroid Build Coastguard Worker #endif
45*eb293b8fSAndroid Build Coastguard Worker
46*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack {
47*eb293b8fSAndroid Build Coastguard Worker
48*eb293b8fSAndroid Build Coastguard Worker class ElfInterfaceTest : public ::testing::Test {
49*eb293b8fSAndroid Build Coastguard Worker protected:
SetUp()50*eb293b8fSAndroid Build Coastguard Worker void SetUp() override {
51*eb293b8fSAndroid Build Coastguard Worker fake_memory_ = new MemoryFake;
52*eb293b8fSAndroid Build Coastguard Worker memory_.reset(fake_memory_);
53*eb293b8fSAndroid Build Coastguard Worker }
54*eb293b8fSAndroid Build Coastguard Worker
SetStringMemory(uint64_t offset,const char * string)55*eb293b8fSAndroid Build Coastguard Worker void SetStringMemory(uint64_t offset, const char* string) {
56*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, string, strlen(string) + 1);
57*eb293b8fSAndroid Build Coastguard Worker }
58*eb293b8fSAndroid Build Coastguard Worker
59*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
60*eb293b8fSAndroid Build Coastguard Worker void SinglePtLoad();
61*eb293b8fSAndroid Build Coastguard Worker
62*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
63*eb293b8fSAndroid Build Coastguard Worker void MultipleExecutablePtLoads();
64*eb293b8fSAndroid Build Coastguard Worker
65*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
66*eb293b8fSAndroid Build Coastguard Worker void MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr();
67*eb293b8fSAndroid Build Coastguard Worker
68*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
69*eb293b8fSAndroid Build Coastguard Worker void NonExecutablePtLoads();
70*eb293b8fSAndroid Build Coastguard Worker
71*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
72*eb293b8fSAndroid Build Coastguard Worker void ManyPhdrs();
73*eb293b8fSAndroid Build Coastguard Worker
74*eb293b8fSAndroid Build Coastguard Worker enum SonameTestEnum : uint8_t {
75*eb293b8fSAndroid Build Coastguard Worker SONAME_NORMAL,
76*eb293b8fSAndroid Build Coastguard Worker SONAME_DTNULL_AFTER,
77*eb293b8fSAndroid Build Coastguard Worker SONAME_DTSIZE_SMALL,
78*eb293b8fSAndroid Build Coastguard Worker SONAME_MISSING_MAP,
79*eb293b8fSAndroid Build Coastguard Worker };
80*eb293b8fSAndroid Build Coastguard Worker
81*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
82*eb293b8fSAndroid Build Coastguard Worker void SonameInit(SonameTestEnum test_type = SONAME_NORMAL);
83*eb293b8fSAndroid Build Coastguard Worker
84*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
85*eb293b8fSAndroid Build Coastguard Worker void Soname();
86*eb293b8fSAndroid Build Coastguard Worker
87*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
88*eb293b8fSAndroid Build Coastguard Worker void SonameAfterDtNull();
89*eb293b8fSAndroid Build Coastguard Worker
90*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
91*eb293b8fSAndroid Build Coastguard Worker void SonameSize();
92*eb293b8fSAndroid Build Coastguard Worker
93*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
94*eb293b8fSAndroid Build Coastguard Worker void SonameMissingMap();
95*eb293b8fSAndroid Build Coastguard Worker
96*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
97*eb293b8fSAndroid Build Coastguard Worker void InitHeadersEhFrameTest();
98*eb293b8fSAndroid Build Coastguard Worker
99*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
100*eb293b8fSAndroid Build Coastguard Worker void InitHeadersDebugFrame();
101*eb293b8fSAndroid Build Coastguard Worker
102*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
103*eb293b8fSAndroid Build Coastguard Worker void InitHeadersEhFrameFail();
104*eb293b8fSAndroid Build Coastguard Worker
105*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
106*eb293b8fSAndroid Build Coastguard Worker void InitHeadersDebugFrameFail();
107*eb293b8fSAndroid Build Coastguard Worker
108*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
109*eb293b8fSAndroid Build Coastguard Worker void InitProgramHeadersMalformed();
110*eb293b8fSAndroid Build Coastguard Worker
111*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
112*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersMalformed();
113*eb293b8fSAndroid Build Coastguard Worker
114*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
115*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersMalformedSymData();
116*eb293b8fSAndroid Build Coastguard Worker
117*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
118*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeaders(uint64_t entry_size);
119*eb293b8fSAndroid Build Coastguard Worker
120*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
121*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersOffsets();
122*eb293b8fSAndroid Build Coastguard Worker
123*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
124*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
125*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias);
126*eb293b8fSAndroid Build Coastguard Worker
127*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
128*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr, uint64_t offset,
129*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias);
130*eb293b8fSAndroid Build Coastguard Worker
131*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
132*eb293b8fSAndroid Build Coastguard Worker void InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr, uint64_t offset,
133*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias);
134*eb293b8fSAndroid Build Coastguard Worker
135*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
136*eb293b8fSAndroid Build Coastguard Worker void CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias);
137*eb293b8fSAndroid Build Coastguard Worker
138*eb293b8fSAndroid Build Coastguard Worker template <typename Sym>
139*eb293b8fSAndroid Build Coastguard Worker void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
140*eb293b8fSAndroid Build Coastguard Worker uint64_t sym_offset, const char* name);
141*eb293b8fSAndroid Build Coastguard Worker
142*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
143*eb293b8fSAndroid Build Coastguard Worker void BuildID();
144*eb293b8fSAndroid Build Coastguard Worker
145*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
146*eb293b8fSAndroid Build Coastguard Worker void BuildIDTwoNotes();
147*eb293b8fSAndroid Build Coastguard Worker
148*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
149*eb293b8fSAndroid Build Coastguard Worker void BuildIDSectionTooSmallForName();
150*eb293b8fSAndroid Build Coastguard Worker
151*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
152*eb293b8fSAndroid Build Coastguard Worker void BuildIDSectionTooSmallForDesc();
153*eb293b8fSAndroid Build Coastguard Worker
154*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
155*eb293b8fSAndroid Build Coastguard Worker void BuildIDSectionTooSmallForHeader();
156*eb293b8fSAndroid Build Coastguard Worker
157*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
158*eb293b8fSAndroid Build Coastguard Worker void CheckLoadBiasInFirstPhdr(int64_t load_bias);
159*eb293b8fSAndroid Build Coastguard Worker
160*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
161*eb293b8fSAndroid Build Coastguard Worker void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, int64_t load_bias);
162*eb293b8fSAndroid Build Coastguard Worker
163*eb293b8fSAndroid Build Coastguard Worker MemoryFake* fake_memory_;
164*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> memory_;
165*eb293b8fSAndroid Build Coastguard Worker };
166*eb293b8fSAndroid Build Coastguard Worker
167*eb293b8fSAndroid Build Coastguard Worker template <typename Sym>
InitSym(uint64_t offset,uint32_t value,uint32_t size,uint32_t name_offset,uint64_t sym_offset,const char * name)168*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
169*eb293b8fSAndroid Build Coastguard Worker uint64_t sym_offset, const char* name) {
170*eb293b8fSAndroid Build Coastguard Worker Sym sym = {};
171*eb293b8fSAndroid Build Coastguard Worker sym.st_info = STT_FUNC;
172*eb293b8fSAndroid Build Coastguard Worker sym.st_value = value;
173*eb293b8fSAndroid Build Coastguard Worker sym.st_size = size;
174*eb293b8fSAndroid Build Coastguard Worker sym.st_name = name_offset;
175*eb293b8fSAndroid Build Coastguard Worker sym.st_shndx = SHN_COMMON;
176*eb293b8fSAndroid Build Coastguard Worker
177*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &sym, sizeof(sym));
178*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
179*eb293b8fSAndroid Build Coastguard Worker }
180*eb293b8fSAndroid Build Coastguard Worker
181*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
SinglePtLoad()182*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::SinglePtLoad() {
183*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
184*eb293b8fSAndroid Build Coastguard Worker
185*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
186*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
187*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 1;
188*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
189*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
190*eb293b8fSAndroid Build Coastguard Worker
191*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
192*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
193*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
194*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
195*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
196*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
197*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
198*eb293b8fSAndroid Build Coastguard Worker
199*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
200*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
201*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000, load_bias);
202*eb293b8fSAndroid Build Coastguard Worker
203*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
204*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(1U, pt_loads.size());
205*eb293b8fSAndroid Build Coastguard Worker LoadInfo load_data = pt_loads.at(0);
206*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0U, load_data.offset);
207*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.table_offset);
208*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10000U, load_data.table_size);
209*eb293b8fSAndroid Build Coastguard Worker }
210*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,single_pt_load_32)211*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, single_pt_load_32) {
212*eb293b8fSAndroid Build Coastguard Worker SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
213*eb293b8fSAndroid Build Coastguard Worker }
214*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,single_pt_load_64)215*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, single_pt_load_64) {
216*eb293b8fSAndroid Build Coastguard Worker SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
217*eb293b8fSAndroid Build Coastguard Worker }
218*eb293b8fSAndroid Build Coastguard Worker
219*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoads()220*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::MultipleExecutablePtLoads() {
221*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
222*eb293b8fSAndroid Build Coastguard Worker
223*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
224*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
225*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 3;
226*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
227*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
228*eb293b8fSAndroid Build Coastguard Worker
229*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
230*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
231*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
232*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
233*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
234*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
235*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
236*eb293b8fSAndroid Build Coastguard Worker
237*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
238*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
239*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x1000;
240*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2001;
241*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10001;
242*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
243*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1001;
244*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
245*eb293b8fSAndroid Build Coastguard Worker
246*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
247*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
248*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x2000;
249*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2002;
250*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10002;
251*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
252*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1002;
253*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
254*eb293b8fSAndroid Build Coastguard Worker
255*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
256*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
257*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000, load_bias);
258*eb293b8fSAndroid Build Coastguard Worker
259*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
260*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(3U, pt_loads.size());
261*eb293b8fSAndroid Build Coastguard Worker
262*eb293b8fSAndroid Build Coastguard Worker LoadInfo load_data = pt_loads.at(0);
263*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0U, load_data.offset);
264*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.table_offset);
265*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10000U, load_data.table_size);
266*eb293b8fSAndroid Build Coastguard Worker
267*eb293b8fSAndroid Build Coastguard Worker load_data = pt_loads.at(0x1000);
268*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x1000U, load_data.offset);
269*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2001U, load_data.table_offset);
270*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10001U, load_data.table_size);
271*eb293b8fSAndroid Build Coastguard Worker
272*eb293b8fSAndroid Build Coastguard Worker load_data = pt_loads.at(0x2000);
273*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.offset);
274*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2002U, load_data.table_offset);
275*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10002U, load_data.table_size);
276*eb293b8fSAndroid Build Coastguard Worker }
277*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_32)278*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_32) {
279*eb293b8fSAndroid Build Coastguard Worker MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
280*eb293b8fSAndroid Build Coastguard Worker }
281*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_64)282*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_64) {
283*eb293b8fSAndroid Build Coastguard Worker MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
284*eb293b8fSAndroid Build Coastguard Worker }
285*eb293b8fSAndroid Build Coastguard Worker
286*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr()287*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
288*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
289*eb293b8fSAndroid Build Coastguard Worker
290*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
291*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
292*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 3;
293*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr) + 100;
294*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
295*eb293b8fSAndroid Build Coastguard Worker
296*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
297*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
298*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
299*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
300*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
301*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
302*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
303*eb293b8fSAndroid Build Coastguard Worker
304*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
305*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
306*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x1000;
307*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2001;
308*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10001;
309*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
310*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1001;
311*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
312*eb293b8fSAndroid Build Coastguard Worker
313*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
314*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
315*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x2000;
316*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2002;
317*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10002;
318*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
319*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1002;
320*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
321*eb293b8fSAndroid Build Coastguard Worker
322*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
323*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
324*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000, load_bias);
325*eb293b8fSAndroid Build Coastguard Worker
326*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
327*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(3U, pt_loads.size());
328*eb293b8fSAndroid Build Coastguard Worker
329*eb293b8fSAndroid Build Coastguard Worker LoadInfo load_data = pt_loads.at(0);
330*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0U, load_data.offset);
331*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.table_offset);
332*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10000U, load_data.table_size);
333*eb293b8fSAndroid Build Coastguard Worker
334*eb293b8fSAndroid Build Coastguard Worker load_data = pt_loads.at(0x1000);
335*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x1000U, load_data.offset);
336*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2001U, load_data.table_offset);
337*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10001U, load_data.table_size);
338*eb293b8fSAndroid Build Coastguard Worker
339*eb293b8fSAndroid Build Coastguard Worker load_data = pt_loads.at(0x2000);
340*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.offset);
341*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2002U, load_data.table_offset);
342*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10002U, load_data.table_size);
343*eb293b8fSAndroid Build Coastguard Worker }
344*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_increments_not_size_of_phdr_32)345*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_32) {
346*eb293b8fSAndroid Build Coastguard Worker MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
347*eb293b8fSAndroid Build Coastguard Worker ElfInterface32>();
348*eb293b8fSAndroid Build Coastguard Worker }
349*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_increments_not_size_of_phdr_64)350*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_64) {
351*eb293b8fSAndroid Build Coastguard Worker MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
352*eb293b8fSAndroid Build Coastguard Worker ElfInterface64>();
353*eb293b8fSAndroid Build Coastguard Worker }
354*eb293b8fSAndroid Build Coastguard Worker
355*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
NonExecutablePtLoads()356*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::NonExecutablePtLoads() {
357*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
358*eb293b8fSAndroid Build Coastguard Worker
359*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
360*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
361*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 3;
362*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
363*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
364*eb293b8fSAndroid Build Coastguard Worker
365*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
366*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
367*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
368*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
369*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R;
370*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
371*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
372*eb293b8fSAndroid Build Coastguard Worker
373*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
374*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
375*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x1000;
376*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2001;
377*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10001;
378*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
379*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1001;
380*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
381*eb293b8fSAndroid Build Coastguard Worker
382*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
383*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
384*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x2000;
385*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2002;
386*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10002;
387*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R;
388*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1002;
389*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
390*eb293b8fSAndroid Build Coastguard Worker
391*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
392*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
393*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x1001, load_bias);
394*eb293b8fSAndroid Build Coastguard Worker
395*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
396*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(1U, pt_loads.size());
397*eb293b8fSAndroid Build Coastguard Worker
398*eb293b8fSAndroid Build Coastguard Worker LoadInfo load_data = pt_loads.at(0x1000);
399*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x1000U, load_data.offset);
400*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2001U, load_data.table_offset);
401*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10001U, load_data.table_size);
402*eb293b8fSAndroid Build Coastguard Worker }
403*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,non_executable_pt_loads_32)404*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, non_executable_pt_loads_32) {
405*eb293b8fSAndroid Build Coastguard Worker NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
406*eb293b8fSAndroid Build Coastguard Worker }
407*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,non_executable_pt_loads_64)408*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, non_executable_pt_loads_64) {
409*eb293b8fSAndroid Build Coastguard Worker NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
410*eb293b8fSAndroid Build Coastguard Worker }
411*eb293b8fSAndroid Build Coastguard Worker
412*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
ManyPhdrs()413*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::ManyPhdrs() {
414*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
415*eb293b8fSAndroid Build Coastguard Worker
416*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
417*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
418*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 7;
419*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
420*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
421*eb293b8fSAndroid Build Coastguard Worker
422*eb293b8fSAndroid Build Coastguard Worker uint64_t phdr_offset = 0x100;
423*eb293b8fSAndroid Build Coastguard Worker
424*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
425*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
426*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
427*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
428*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
429*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
430*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
431*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
432*eb293b8fSAndroid Build Coastguard Worker
433*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
434*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_GNU_EH_FRAME;
435*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
436*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
437*eb293b8fSAndroid Build Coastguard Worker
438*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
439*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_DYNAMIC;
440*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
441*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
442*eb293b8fSAndroid Build Coastguard Worker
443*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
444*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_INTERP;
445*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
446*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
447*eb293b8fSAndroid Build Coastguard Worker
448*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
449*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_NOTE;
450*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
451*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
452*eb293b8fSAndroid Build Coastguard Worker
453*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
454*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_SHLIB;
455*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
456*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
457*eb293b8fSAndroid Build Coastguard Worker
458*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
459*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_GNU_EH_FRAME;
460*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
461*eb293b8fSAndroid Build Coastguard Worker
462*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
463*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
464*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000, load_bias);
465*eb293b8fSAndroid Build Coastguard Worker
466*eb293b8fSAndroid Build Coastguard Worker const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
467*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(1U, pt_loads.size());
468*eb293b8fSAndroid Build Coastguard Worker
469*eb293b8fSAndroid Build Coastguard Worker LoadInfo load_data = pt_loads.at(0);
470*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0U, load_data.offset);
471*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, load_data.table_offset);
472*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x10000U, load_data.table_size);
473*eb293b8fSAndroid Build Coastguard Worker }
474*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,many_phdrs_32)475*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, many_phdrs_32) {
476*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
477*eb293b8fSAndroid Build Coastguard Worker }
478*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,many_phdrs_64)479*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, many_phdrs_64) {
480*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
481*eb293b8fSAndroid Build Coastguard Worker }
482*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,arm32)483*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, arm32) {
484*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceArm elf_arm(memory_);
485*eb293b8fSAndroid Build Coastguard Worker
486*eb293b8fSAndroid Build Coastguard Worker Elf32_Ehdr ehdr = {};
487*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
488*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 1;
489*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Elf32_Phdr);
490*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
491*eb293b8fSAndroid Build Coastguard Worker
492*eb293b8fSAndroid Build Coastguard Worker Elf32_Phdr phdr = {};
493*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_ARM_EXIDX;
494*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x2000;
495*eb293b8fSAndroid Build Coastguard Worker phdr.p_filesz = 16;
496*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
497*eb293b8fSAndroid Build Coastguard Worker
498*eb293b8fSAndroid Build Coastguard Worker // Add arm exidx entries.
499*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x2000, 0x1000);
500*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x2008, 0x1000);
501*eb293b8fSAndroid Build Coastguard Worker
502*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
503*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf_arm.Init(&load_bias));
504*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
505*eb293b8fSAndroid Build Coastguard Worker
506*eb293b8fSAndroid Build Coastguard Worker std::vector<uint32_t> entries;
507*eb293b8fSAndroid Build Coastguard Worker for (auto addr : elf_arm) {
508*eb293b8fSAndroid Build Coastguard Worker entries.push_back(addr);
509*eb293b8fSAndroid Build Coastguard Worker }
510*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, entries.size());
511*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x3000U, entries[0]);
512*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x3008U, entries[1]);
513*eb293b8fSAndroid Build Coastguard Worker
514*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(0x2000U, elf_arm.start_offset());
515*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(2U, elf_arm.total_entries());
516*eb293b8fSAndroid Build Coastguard Worker }
517*eb293b8fSAndroid Build Coastguard Worker
518*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
SonameInit(SonameTestEnum test_type)519*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
520*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
521*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = 0x200;
522*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 2;
523*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
524*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
525*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 1;
526*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
527*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
528*eb293b8fSAndroid Build Coastguard Worker
529*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
530*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
531*eb293b8fSAndroid Build Coastguard Worker if (test_type == SONAME_MISSING_MAP) {
532*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x20100;
533*eb293b8fSAndroid Build Coastguard Worker } else {
534*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x10100;
535*eb293b8fSAndroid Build Coastguard Worker }
536*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x10000;
537*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
538*eb293b8fSAndroid Build Coastguard Worker
539*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
540*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_DYNAMIC;
541*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x2000;
542*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = sizeof(Dyn) * 3;
543*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
544*eb293b8fSAndroid Build Coastguard Worker
545*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
546*eb293b8fSAndroid Build Coastguard Worker Dyn dyn;
547*eb293b8fSAndroid Build Coastguard Worker
548*eb293b8fSAndroid Build Coastguard Worker dyn.d_tag = DT_STRTAB;
549*eb293b8fSAndroid Build Coastguard Worker dyn.d_un.d_ptr = 0x10100;
550*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &dyn, sizeof(dyn));
551*eb293b8fSAndroid Build Coastguard Worker offset += sizeof(dyn);
552*eb293b8fSAndroid Build Coastguard Worker
553*eb293b8fSAndroid Build Coastguard Worker dyn.d_tag = DT_STRSZ;
554*eb293b8fSAndroid Build Coastguard Worker if (test_type == SONAME_DTSIZE_SMALL) {
555*eb293b8fSAndroid Build Coastguard Worker dyn.d_un.d_val = 0x10;
556*eb293b8fSAndroid Build Coastguard Worker } else {
557*eb293b8fSAndroid Build Coastguard Worker dyn.d_un.d_val = 0x1000;
558*eb293b8fSAndroid Build Coastguard Worker }
559*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &dyn, sizeof(dyn));
560*eb293b8fSAndroid Build Coastguard Worker offset += sizeof(dyn);
561*eb293b8fSAndroid Build Coastguard Worker
562*eb293b8fSAndroid Build Coastguard Worker if (test_type == SONAME_DTNULL_AFTER) {
563*eb293b8fSAndroid Build Coastguard Worker dyn.d_tag = DT_NULL;
564*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &dyn, sizeof(dyn));
565*eb293b8fSAndroid Build Coastguard Worker offset += sizeof(dyn);
566*eb293b8fSAndroid Build Coastguard Worker }
567*eb293b8fSAndroid Build Coastguard Worker
568*eb293b8fSAndroid Build Coastguard Worker dyn.d_tag = DT_SONAME;
569*eb293b8fSAndroid Build Coastguard Worker dyn.d_un.d_val = 0x10;
570*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &dyn, sizeof(dyn));
571*eb293b8fSAndroid Build Coastguard Worker offset += sizeof(dyn);
572*eb293b8fSAndroid Build Coastguard Worker
573*eb293b8fSAndroid Build Coastguard Worker dyn.d_tag = DT_NULL;
574*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &dyn, sizeof(dyn));
575*eb293b8fSAndroid Build Coastguard Worker
576*eb293b8fSAndroid Build Coastguard Worker SetStringMemory(0x10010, "fake_soname.so");
577*eb293b8fSAndroid Build Coastguard Worker }
578*eb293b8fSAndroid Build Coastguard Worker
579*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
Soname()580*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::Soname() {
581*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
582*eb293b8fSAndroid Build Coastguard Worker
583*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
584*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
585*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
586*eb293b8fSAndroid Build Coastguard Worker
587*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("fake_soname.so", elf->GetSoname());
588*eb293b8fSAndroid Build Coastguard Worker }
589*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_32)590*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_32) {
591*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
592*eb293b8fSAndroid Build Coastguard Worker Soname<ElfInterface32>();
593*eb293b8fSAndroid Build Coastguard Worker }
594*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_64)595*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_64) {
596*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
597*eb293b8fSAndroid Build Coastguard Worker Soname<ElfInterface64>();
598*eb293b8fSAndroid Build Coastguard Worker }
599*eb293b8fSAndroid Build Coastguard Worker
600*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
SonameAfterDtNull()601*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::SonameAfterDtNull() {
602*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
603*eb293b8fSAndroid Build Coastguard Worker
604*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
605*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
606*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
607*eb293b8fSAndroid Build Coastguard Worker
608*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetSoname());
609*eb293b8fSAndroid Build Coastguard Worker }
610*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_after_dt_null_32)611*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_after_dt_null_32) {
612*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
613*eb293b8fSAndroid Build Coastguard Worker SonameAfterDtNull<ElfInterface32>();
614*eb293b8fSAndroid Build Coastguard Worker }
615*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_after_dt_null_64)616*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_after_dt_null_64) {
617*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
618*eb293b8fSAndroid Build Coastguard Worker SonameAfterDtNull<ElfInterface64>();
619*eb293b8fSAndroid Build Coastguard Worker }
620*eb293b8fSAndroid Build Coastguard Worker
621*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
SonameSize()622*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::SonameSize() {
623*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
624*eb293b8fSAndroid Build Coastguard Worker
625*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
626*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
627*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
628*eb293b8fSAndroid Build Coastguard Worker
629*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetSoname());
630*eb293b8fSAndroid Build Coastguard Worker }
631*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_size_32)632*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_size_32) {
633*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
634*eb293b8fSAndroid Build Coastguard Worker SonameSize<ElfInterface32>();
635*eb293b8fSAndroid Build Coastguard Worker }
636*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_size_64)637*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_size_64) {
638*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
639*eb293b8fSAndroid Build Coastguard Worker SonameSize<ElfInterface64>();
640*eb293b8fSAndroid Build Coastguard Worker }
641*eb293b8fSAndroid Build Coastguard Worker
642*eb293b8fSAndroid Build Coastguard Worker // Verify that there is no map from STRTAB in the dynamic section to a
643*eb293b8fSAndroid Build Coastguard Worker // STRTAB entry in the section headers.
644*eb293b8fSAndroid Build Coastguard Worker template <typename ElfInterfaceType>
SonameMissingMap()645*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::SonameMissingMap() {
646*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
647*eb293b8fSAndroid Build Coastguard Worker
648*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
649*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
650*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
651*eb293b8fSAndroid Build Coastguard Worker
652*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetSoname());
653*eb293b8fSAndroid Build Coastguard Worker }
654*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_missing_map_32)655*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_missing_map_32) {
656*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
657*eb293b8fSAndroid Build Coastguard Worker SonameMissingMap<ElfInterface32>();
658*eb293b8fSAndroid Build Coastguard Worker }
659*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,soname_missing_map_64)660*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, soname_missing_map_64) {
661*eb293b8fSAndroid Build Coastguard Worker SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
662*eb293b8fSAndroid Build Coastguard Worker SonameMissingMap<ElfInterface64>();
663*eb293b8fSAndroid Build Coastguard Worker }
664*eb293b8fSAndroid Build Coastguard Worker
665*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
InitHeadersEhFrameTest()666*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitHeadersEhFrameTest() {
667*eb293b8fSAndroid Build Coastguard Worker ElfType elf(memory_);
668*eb293b8fSAndroid Build Coastguard Worker
669*eb293b8fSAndroid Build Coastguard Worker elf.FakeSetEhFrameInfo(SectionInfo{.offset = 0x10000});
670*eb293b8fSAndroid Build Coastguard Worker elf.FakeSetDebugFrameInfo(SectionInfo{});
671*eb293b8fSAndroid Build Coastguard Worker
672*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(
673*eb293b8fSAndroid Build Coastguard Worker 0x10000, std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
674*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x10004, 0x500);
675*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x10008, 250);
676*eb293b8fSAndroid Build Coastguard Worker
677*eb293b8fSAndroid Build Coastguard Worker elf.InitHeaders();
678*eb293b8fSAndroid Build Coastguard Worker
679*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf.eh_frame() == nullptr);
680*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf.debug_frame() == nullptr);
681*eb293b8fSAndroid Build Coastguard Worker }
682*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_headers_eh_frame_32)683*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_headers_eh_frame_32) {
684*eb293b8fSAndroid Build Coastguard Worker InitHeadersEhFrameTest<ElfInterface32Fake>();
685*eb293b8fSAndroid Build Coastguard Worker }
686*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_headers_eh_frame_64)687*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_headers_eh_frame_64) {
688*eb293b8fSAndroid Build Coastguard Worker InitHeadersEhFrameTest<ElfInterface64Fake>();
689*eb293b8fSAndroid Build Coastguard Worker }
690*eb293b8fSAndroid Build Coastguard Worker
691*eb293b8fSAndroid Build Coastguard Worker template <typename ElfType>
InitHeadersDebugFrame()692*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitHeadersDebugFrame() {
693*eb293b8fSAndroid Build Coastguard Worker ElfType elf(memory_);
694*eb293b8fSAndroid Build Coastguard Worker
695*eb293b8fSAndroid Build Coastguard Worker elf.FakeSetEhFrameInfo(SectionInfo{});
696*eb293b8fSAndroid Build Coastguard Worker elf.FakeSetDebugFrameInfo(SectionInfo{.offset = 0x5000, .size = 0x200});
697*eb293b8fSAndroid Build Coastguard Worker
698*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x5000, 0xfc);
699*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x5004, 0xffffffff);
700*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
701*eb293b8fSAndroid Build Coastguard Worker
702*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x5100, 0xfc);
703*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x5104, 0);
704*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x5108, 0x1500);
705*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x510c, 0x200);
706*eb293b8fSAndroid Build Coastguard Worker
707*eb293b8fSAndroid Build Coastguard Worker elf.InitHeaders();
708*eb293b8fSAndroid Build Coastguard Worker
709*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf.eh_frame() == nullptr);
710*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf.debug_frame() == nullptr);
711*eb293b8fSAndroid Build Coastguard Worker }
712*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_headers_debug_frame_32)713*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_headers_debug_frame_32) {
714*eb293b8fSAndroid Build Coastguard Worker InitHeadersDebugFrame<ElfInterface32Fake>();
715*eb293b8fSAndroid Build Coastguard Worker }
716*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_headers_debug_frame_64)717*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_headers_debug_frame_64) {
718*eb293b8fSAndroid Build Coastguard Worker InitHeadersDebugFrame<ElfInterface64Fake>();
719*eb293b8fSAndroid Build Coastguard Worker }
720*eb293b8fSAndroid Build Coastguard Worker
721*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
InitProgramHeadersMalformed()722*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitProgramHeadersMalformed() {
723*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
724*eb293b8fSAndroid Build Coastguard Worker
725*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
726*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
727*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 3;
728*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
729*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
730*eb293b8fSAndroid Build Coastguard Worker
731*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
732*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
733*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
734*eb293b8fSAndroid Build Coastguard Worker }
735*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_program_headers_malformed_32)736*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_program_headers_malformed_32) {
737*eb293b8fSAndroid Build Coastguard Worker InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
738*eb293b8fSAndroid Build Coastguard Worker }
739*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_program_headers_malformed_64)740*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_program_headers_malformed_64) {
741*eb293b8fSAndroid Build Coastguard Worker InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
742*eb293b8fSAndroid Build Coastguard Worker }
743*eb293b8fSAndroid Build Coastguard Worker
744*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersMalformed()745*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersMalformed() {
746*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
747*eb293b8fSAndroid Build Coastguard Worker
748*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
749*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = 0x1000;
750*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 10;
751*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
752*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
753*eb293b8fSAndroid Build Coastguard Worker
754*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
755*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
756*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
757*eb293b8fSAndroid Build Coastguard Worker }
758*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_malformed_32)759*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_malformed_32) {
760*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
761*eb293b8fSAndroid Build Coastguard Worker }
762*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_malformed_64)763*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_malformed_64) {
764*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
765*eb293b8fSAndroid Build Coastguard Worker }
766*eb293b8fSAndroid Build Coastguard Worker
767*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersMalformedSymData()768*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
769*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
770*eb293b8fSAndroid Build Coastguard Worker
771*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x1000;
772*eb293b8fSAndroid Build Coastguard Worker
773*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
774*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
775*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 5;
776*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
777*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
778*eb293b8fSAndroid Build Coastguard Worker
779*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
780*eb293b8fSAndroid Build Coastguard Worker
781*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
782*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_SYMTAB;
783*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 4;
784*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x5000;
785*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x5000;
786*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
787*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = shdr.sh_entsize * 10;
788*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
789*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
790*eb293b8fSAndroid Build Coastguard Worker
791*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
792*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_DYNSYM;
793*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 10;
794*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x6000;
795*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x6000;
796*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
797*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = shdr.sh_entsize * 10;
798*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
799*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
800*eb293b8fSAndroid Build Coastguard Worker
801*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
802*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_DYNSYM;
803*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
804*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x6000;
805*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x6000;
806*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
807*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = shdr.sh_entsize * 10;
808*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
809*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
810*eb293b8fSAndroid Build Coastguard Worker
811*eb293b8fSAndroid Build Coastguard Worker // The string data for the entries.
812*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
813*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
814*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
815*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
816*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
817*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
818*eb293b8fSAndroid Build Coastguard Worker
819*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
820*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
821*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
822*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->debug_frame_info().offset);
823*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->debug_frame_info().size);
824*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->gnu_debugdata_offset());
825*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->gnu_debugdata_size());
826*eb293b8fSAndroid Build Coastguard Worker
827*eb293b8fSAndroid Build Coastguard Worker SharedString name;
828*eb293b8fSAndroid Build Coastguard Worker uint64_t name_offset;
829*eb293b8fSAndroid Build Coastguard Worker ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
830*eb293b8fSAndroid Build Coastguard Worker }
831*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_malformed_symdata_32)832*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_32) {
833*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
834*eb293b8fSAndroid Build Coastguard Worker }
835*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_malformed_symdata_64)836*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_64) {
837*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
838*eb293b8fSAndroid Build Coastguard Worker }
839*eb293b8fSAndroid Build Coastguard Worker
840*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
InitSectionHeaders(uint64_t entry_size)841*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
842*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
843*eb293b8fSAndroid Build Coastguard Worker
844*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x1000;
845*eb293b8fSAndroid Build Coastguard Worker
846*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
847*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
848*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 5;
849*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = entry_size;
850*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
851*eb293b8fSAndroid Build Coastguard Worker
852*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
853*eb293b8fSAndroid Build Coastguard Worker
854*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
855*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_SYMTAB;
856*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 4;
857*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x5000;
858*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x5000;
859*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = sizeof(Sym);
860*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = shdr.sh_entsize * 10;
861*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
862*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
863*eb293b8fSAndroid Build Coastguard Worker
864*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
865*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_DYNSYM;
866*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 4;
867*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x6000;
868*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x6000;
869*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = sizeof(Sym);
870*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = shdr.sh_entsize * 10;
871*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
872*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
873*eb293b8fSAndroid Build Coastguard Worker
874*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
875*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
876*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0xa000;
877*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
878*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
879*eb293b8fSAndroid Build Coastguard Worker
880*eb293b8fSAndroid Build Coastguard Worker // The string data for the entries.
881*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
882*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
883*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
884*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
885*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
886*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
887*eb293b8fSAndroid Build Coastguard Worker
888*eb293b8fSAndroid Build Coastguard Worker InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
889*eb293b8fSAndroid Build Coastguard Worker InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
890*eb293b8fSAndroid Build Coastguard Worker
891*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
892*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
893*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
894*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->debug_frame_info().offset);
895*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->debug_frame_info().size);
896*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->gnu_debugdata_offset());
897*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->gnu_debugdata_size());
898*eb293b8fSAndroid Build Coastguard Worker
899*eb293b8fSAndroid Build Coastguard Worker // Look in the first symbol table.
900*eb293b8fSAndroid Build Coastguard Worker SharedString name;
901*eb293b8fSAndroid Build Coastguard Worker uint64_t name_offset;
902*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
903*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("function_one", name);
904*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(16U, name_offset);
905*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
906*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ("function_two", name);
907*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(32U, name_offset);
908*eb293b8fSAndroid Build Coastguard Worker }
909*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_32)910*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_32) {
911*eb293b8fSAndroid Build Coastguard Worker InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
912*eb293b8fSAndroid Build Coastguard Worker }
913*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_64)914*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_64) {
915*eb293b8fSAndroid Build Coastguard Worker InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
916*eb293b8fSAndroid Build Coastguard Worker }
917*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_non_std_entry_size_32)918*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_32) {
919*eb293b8fSAndroid Build Coastguard Worker InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
920*eb293b8fSAndroid Build Coastguard Worker }
921*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_non_std_entry_size_64)922*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_64) {
923*eb293b8fSAndroid Build Coastguard Worker InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
924*eb293b8fSAndroid Build Coastguard Worker }
925*eb293b8fSAndroid Build Coastguard Worker
926*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsets()927*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersOffsets() {
928*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
929*eb293b8fSAndroid Build Coastguard Worker
930*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
931*eb293b8fSAndroid Build Coastguard Worker
932*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
933*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
934*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 7;
935*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
936*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
937*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
938*eb293b8fSAndroid Build Coastguard Worker
939*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
940*eb293b8fSAndroid Build Coastguard Worker
941*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
942*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
943*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
944*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x200;
945*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x5000;
946*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x5000;
947*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
948*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x800;
949*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
950*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
951*eb293b8fSAndroid Build Coastguard Worker
952*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
953*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
954*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
955*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
956*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
957*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
958*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
959*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
960*eb293b8fSAndroid Build Coastguard Worker
961*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
962*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
963*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
964*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x100;
965*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x6000;
966*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x6000;
967*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
968*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x500;
969*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
970*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
971*eb293b8fSAndroid Build Coastguard Worker
972*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
973*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
974*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
975*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x300;
976*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x7000;
977*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x7000;
978*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
979*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x800;
980*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
981*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
982*eb293b8fSAndroid Build Coastguard Worker
983*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
984*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
985*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
986*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x400;
987*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0xa000;
988*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xa000;
989*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
990*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0xf00;
991*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
992*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
993*eb293b8fSAndroid Build Coastguard Worker
994*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
995*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
996*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
997*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0xb000;
998*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
999*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0xf00;
1000*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1001*eb293b8fSAndroid Build Coastguard Worker
1002*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
1003*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
1004*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
1005*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1006*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1007*eb293b8fSAndroid Build Coastguard Worker
1008*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1009*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1010*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1011*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x6000U, elf->debug_frame_info().offset);
1012*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, elf->debug_frame_info().bias);
1013*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x500U, elf->debug_frame_info().size);
1014*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->debug_frame_info().flags);
1015*eb293b8fSAndroid Build Coastguard Worker
1016*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
1017*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
1018*eb293b8fSAndroid Build Coastguard Worker
1019*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x7000U, elf->eh_frame_info().offset);
1020*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, elf->eh_frame_info().bias);
1021*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x800U, elf->eh_frame_info().size);
1022*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_info().flags);
1023*eb293b8fSAndroid Build Coastguard Worker
1024*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xa000U, elf->eh_frame_hdr_info().offset);
1025*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, elf->eh_frame_hdr_info().bias);
1026*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xf00U, elf->eh_frame_hdr_info().size);
1027*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_hdr_info().flags);
1028*eb293b8fSAndroid Build Coastguard Worker
1029*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
1030*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
1031*eb293b8fSAndroid Build Coastguard Worker }
1032*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_32)1033*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_32) {
1034*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1035*eb293b8fSAndroid Build Coastguard Worker }
1036*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_64)1037*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_64) {
1038*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1039*eb293b8fSAndroid Build Coastguard Worker }
1040*eb293b8fSAndroid Build Coastguard Worker
1041*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1042*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
1043*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias) {
1044*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1045*eb293b8fSAndroid Build Coastguard Worker
1046*eb293b8fSAndroid Build Coastguard Worker uint64_t elf_offset = 0x2000;
1047*eb293b8fSAndroid Build Coastguard Worker
1048*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1049*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = elf_offset;
1050*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 4;
1051*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1052*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1053*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1054*eb293b8fSAndroid Build Coastguard Worker
1055*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1056*eb293b8fSAndroid Build Coastguard Worker
1057*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1058*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1059*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
1060*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x200;
1061*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x8000;
1062*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x8000;
1063*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
1064*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x800;
1065*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1066*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1067*eb293b8fSAndroid Build Coastguard Worker
1068*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1069*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1070*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1071*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1072*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1073*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1074*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1075*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1076*eb293b8fSAndroid Build Coastguard Worker
1077*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1078*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1079*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
1080*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x100;
1081*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = addr;
1082*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = offset;
1083*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
1084*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x500;
1085*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1086*eb293b8fSAndroid Build Coastguard Worker
1087*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1088*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1089*eb293b8fSAndroid Build Coastguard Worker
1090*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1091*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1092*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1093*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(offset, elf->eh_frame_info().offset);
1094*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(expected_bias, elf->eh_frame_info().bias);
1095*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x500U, elf->eh_frame_info().size);
1096*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_info().flags);
1097*eb293b8fSAndroid Build Coastguard Worker
1098*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x8000U, elf->eh_frame_hdr_info().offset);
1099*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, elf->eh_frame_hdr_info().bias);
1100*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x800U, elf->eh_frame_hdr_info().size);
1101*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_hdr_info().flags);
1102*eb293b8fSAndroid Build Coastguard Worker }
1103*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_zero_32)1104*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_32) {
1105*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x4000,
1106*eb293b8fSAndroid Build Coastguard Worker 0x4000, 0);
1107*eb293b8fSAndroid Build Coastguard Worker }
1108*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_zero_64)1109*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_64) {
1110*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0x6000,
1111*eb293b8fSAndroid Build Coastguard Worker 0x6000, 0);
1112*eb293b8fSAndroid Build Coastguard Worker }
1113*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_positive_32)1114*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_32) {
1115*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1116*eb293b8fSAndroid Build Coastguard Worker 0x5000, 0x4000, 0x1000);
1117*eb293b8fSAndroid Build Coastguard Worker }
1118*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_positive_64)1119*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_64) {
1120*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1121*eb293b8fSAndroid Build Coastguard Worker 0x6000, 0x4000, 0x2000);
1122*eb293b8fSAndroid Build Coastguard Worker }
1123*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_negative_32)1124*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_32) {
1125*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1126*eb293b8fSAndroid Build Coastguard Worker 0x3000, 0x4000, -0x1000);
1127*eb293b8fSAndroid Build Coastguard Worker }
1128*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_negative_64)1129*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_64) {
1130*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1131*eb293b8fSAndroid Build Coastguard Worker 0x6000, 0x9000, -0x3000);
1132*eb293b8fSAndroid Build Coastguard Worker }
1133*eb293b8fSAndroid Build Coastguard Worker
1134*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1135*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,
1136*eb293b8fSAndroid Build Coastguard Worker uint64_t offset,
1137*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias) {
1138*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1139*eb293b8fSAndroid Build Coastguard Worker
1140*eb293b8fSAndroid Build Coastguard Worker uint64_t elf_offset = 0x2000;
1141*eb293b8fSAndroid Build Coastguard Worker
1142*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1143*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = elf_offset;
1144*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 4;
1145*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1146*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1147*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1148*eb293b8fSAndroid Build Coastguard Worker
1149*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1150*eb293b8fSAndroid Build Coastguard Worker
1151*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1152*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1153*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
1154*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x200;
1155*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = addr;
1156*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = offset;
1157*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
1158*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x800;
1159*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1160*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1161*eb293b8fSAndroid Build Coastguard Worker
1162*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1163*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1164*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1165*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1166*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1167*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1168*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1169*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1170*eb293b8fSAndroid Build Coastguard Worker
1171*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1172*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1173*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
1174*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x100;
1175*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x5000;
1176*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x5000;
1177*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
1178*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x500;
1179*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1180*eb293b8fSAndroid Build Coastguard Worker
1181*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1182*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1183*eb293b8fSAndroid Build Coastguard Worker
1184*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1185*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1186*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1187*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x5000U, elf->eh_frame_info().offset);
1188*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, elf->eh_frame_info().bias);
1189*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x500U, elf->eh_frame_info().size);
1190*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_info().flags);
1191*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(offset, elf->eh_frame_hdr_info().offset);
1192*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(expected_bias, elf->eh_frame_hdr_info().bias);
1193*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x800U, elf->eh_frame_hdr_info().size);
1194*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, elf->eh_frame_hdr_info().flags);
1195*eb293b8fSAndroid Build Coastguard Worker }
1196*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32)1197*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32) {
1198*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x9000,
1199*eb293b8fSAndroid Build Coastguard Worker 0x9000, 0);
1200*eb293b8fSAndroid Build Coastguard Worker }
1201*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64)1202*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64) {
1203*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1204*eb293b8fSAndroid Build Coastguard Worker 0xa000, 0);
1205*eb293b8fSAndroid Build Coastguard Worker }
1206*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32)1207*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32) {
1208*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1209*eb293b8fSAndroid Build Coastguard Worker 0x9000, 0x4000, 0x5000);
1210*eb293b8fSAndroid Build Coastguard Worker }
1211*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64)1212*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64) {
1213*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1214*eb293b8fSAndroid Build Coastguard Worker 0x6000, 0x1000, 0x5000);
1215*eb293b8fSAndroid Build Coastguard Worker }
1216*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32)1217*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32) {
1218*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1219*eb293b8fSAndroid Build Coastguard Worker 0x3000, 0x5000, -0x2000);
1220*eb293b8fSAndroid Build Coastguard Worker }
1221*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64)1222*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64) {
1223*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1224*eb293b8fSAndroid Build Coastguard Worker 0x5000, 0x9000, -0x4000);
1225*eb293b8fSAndroid Build Coastguard Worker }
1226*eb293b8fSAndroid Build Coastguard Worker
1227*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1228*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,
1229*eb293b8fSAndroid Build Coastguard Worker uint64_t offset,
1230*eb293b8fSAndroid Build Coastguard Worker int64_t expected_bias) {
1231*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1232*eb293b8fSAndroid Build Coastguard Worker
1233*eb293b8fSAndroid Build Coastguard Worker uint64_t elf_offset = 0x2000;
1234*eb293b8fSAndroid Build Coastguard Worker
1235*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1236*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = elf_offset;
1237*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1238*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1239*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1240*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1241*eb293b8fSAndroid Build Coastguard Worker
1242*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1243*eb293b8fSAndroid Build Coastguard Worker
1244*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1245*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1246*eb293b8fSAndroid Build Coastguard Worker shdr.sh_link = 2;
1247*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x100;
1248*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = addr;
1249*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = offset;
1250*eb293b8fSAndroid Build Coastguard Worker shdr.sh_entsize = 0x100;
1251*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x800;
1252*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1253*eb293b8fSAndroid Build Coastguard Worker elf_offset += ehdr.e_shentsize;
1254*eb293b8fSAndroid Build Coastguard Worker
1255*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1256*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1257*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1258*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1259*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1260*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1261*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(elf_offset, &shdr, sizeof(shdr));
1262*eb293b8fSAndroid Build Coastguard Worker
1263*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
1264*eb293b8fSAndroid Build Coastguard Worker
1265*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1266*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1267*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1268*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(offset, elf->debug_frame_info().offset);
1269*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(expected_bias, elf->debug_frame_info().bias);
1270*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x800U, elf->debug_frame_info().size);
1271*eb293b8fSAndroid Build Coastguard Worker }
1272*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_zero_32)1273*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_32) {
1274*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x5000,
1275*eb293b8fSAndroid Build Coastguard Worker 0x5000, 0);
1276*eb293b8fSAndroid Build Coastguard Worker }
1277*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_zero_64)1278*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_64) {
1279*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1280*eb293b8fSAndroid Build Coastguard Worker 0xa000, 0);
1281*eb293b8fSAndroid Build Coastguard Worker }
1282*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_positive_32)1283*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_32) {
1284*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1285*eb293b8fSAndroid Build Coastguard Worker 0x5000, 0x2000, 0x3000);
1286*eb293b8fSAndroid Build Coastguard Worker }
1287*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_positive_64)1288*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_64) {
1289*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1290*eb293b8fSAndroid Build Coastguard Worker 0x7000, 0x1000, 0x6000);
1291*eb293b8fSAndroid Build Coastguard Worker }
1292*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_negative_32)1293*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_32) {
1294*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1295*eb293b8fSAndroid Build Coastguard Worker 0x6000, 0x7000, -0x1000);
1296*eb293b8fSAndroid Build Coastguard Worker }
1297*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_negative_64)1298*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_64) {
1299*eb293b8fSAndroid Build Coastguard Worker InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1300*eb293b8fSAndroid Build Coastguard Worker 0x3000, 0x5000, -0x2000);
1301*eb293b8fSAndroid Build Coastguard Worker }
1302*eb293b8fSAndroid Build Coastguard Worker
1303*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckGnuEhFrame(uint64_t addr,uint64_t offset,int64_t expected_bias)1304*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias) {
1305*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(memory_));
1306*eb293b8fSAndroid Build Coastguard Worker
1307*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1308*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
1309*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 2;
1310*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
1311*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1312*eb293b8fSAndroid Build Coastguard Worker
1313*eb293b8fSAndroid Build Coastguard Worker uint64_t phdr_offset = 0x100;
1314*eb293b8fSAndroid Build Coastguard Worker
1315*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
1316*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1317*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
1318*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1319*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1320*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
1321*eb293b8fSAndroid Build Coastguard Worker phdr_offset += sizeof(phdr);
1322*eb293b8fSAndroid Build Coastguard Worker
1323*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
1324*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_GNU_EH_FRAME;
1325*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = addr;
1326*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = offset;
1327*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(phdr_offset, &phdr, sizeof(phdr));
1328*eb293b8fSAndroid Build Coastguard Worker
1329*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1330*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1331*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1332*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(expected_bias, elf->eh_frame_hdr_info().bias);
1333*eb293b8fSAndroid Build Coastguard Worker }
1334*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_zero_section_bias_32)1335*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_32) {
1336*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x4000, 0);
1337*eb293b8fSAndroid Build Coastguard Worker }
1338*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_zero_section_bias_64)1339*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_64) {
1340*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x4000, 0);
1341*eb293b8fSAndroid Build Coastguard Worker }
1342*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_positive_section_bias_32)1343*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_32) {
1344*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x1000, 0x3000);
1345*eb293b8fSAndroid Build Coastguard Worker }
1346*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_positive_section_bias_64)1347*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_64) {
1348*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x1000, 0x3000);
1349*eb293b8fSAndroid Build Coastguard Worker }
1350*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_negative_section_bias_32)1351*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_32) {
1352*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x5000,
1353*eb293b8fSAndroid Build Coastguard Worker -0x1000);
1354*eb293b8fSAndroid Build Coastguard Worker }
1355*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,eh_frame_negative_section_bias_64)1356*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_64) {
1357*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x5000,
1358*eb293b8fSAndroid Build Coastguard Worker -0x1000);
1359*eb293b8fSAndroid Build Coastguard Worker }
1360*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,is_valid_pc_from_pt_load)1361*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
1362*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterface32(memory_));
1363*eb293b8fSAndroid Build Coastguard Worker
1364*eb293b8fSAndroid Build Coastguard Worker Elf32_Ehdr ehdr = {};
1365*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
1366*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 1;
1367*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Elf32_Phdr);
1368*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1369*eb293b8fSAndroid Build Coastguard Worker
1370*eb293b8fSAndroid Build Coastguard Worker Elf32_Phdr phdr = {};
1371*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1372*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0;
1373*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
1374*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1375*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1376*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
1377*eb293b8fSAndroid Build Coastguard Worker
1378*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1379*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1380*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1381*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0));
1382*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x5000));
1383*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0xffff));
1384*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x10000));
1385*eb293b8fSAndroid Build Coastguard Worker }
1386*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,is_valid_pc_from_pt_load_non_zero_load_bias)1387*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1388*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterface32(memory_));
1389*eb293b8fSAndroid Build Coastguard Worker
1390*eb293b8fSAndroid Build Coastguard Worker Elf32_Ehdr ehdr = {};
1391*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
1392*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 1;
1393*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Elf32_Phdr);
1394*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1395*eb293b8fSAndroid Build Coastguard Worker
1396*eb293b8fSAndroid Build Coastguard Worker Elf32_Phdr phdr = {};
1397*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1398*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
1399*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
1400*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1401*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1402*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
1403*eb293b8fSAndroid Build Coastguard Worker
1404*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1405*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1406*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x2000, load_bias);
1407*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0));
1408*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x1000));
1409*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x1fff));
1410*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x2000));
1411*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x5000));
1412*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x11fff));
1413*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x12000));
1414*eb293b8fSAndroid Build Coastguard Worker }
1415*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,is_valid_pc_from_debug_frame)1416*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1417*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterface32(memory_));
1418*eb293b8fSAndroid Build Coastguard Worker
1419*eb293b8fSAndroid Build Coastguard Worker uint64_t sh_offset = 0x100;
1420*eb293b8fSAndroid Build Coastguard Worker
1421*eb293b8fSAndroid Build Coastguard Worker Elf32_Ehdr ehdr = {};
1422*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 1;
1423*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = sh_offset;
1424*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Elf32_Shdr);
1425*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1426*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1427*eb293b8fSAndroid Build Coastguard Worker
1428*eb293b8fSAndroid Build Coastguard Worker Elf32_Shdr shdr = {};
1429*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NULL;
1430*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1431*eb293b8fSAndroid Build Coastguard Worker
1432*eb293b8fSAndroid Build Coastguard Worker sh_offset += sizeof(shdr);
1433*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1434*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1435*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 1;
1436*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x500;
1437*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x100;
1438*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1439*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x500, ".debug_frame");
1440*eb293b8fSAndroid Build Coastguard Worker
1441*eb293b8fSAndroid Build Coastguard Worker sh_offset += sizeof(shdr);
1442*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1443*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1444*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0;
1445*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x600;
1446*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x600;
1447*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x200;
1448*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1449*eb293b8fSAndroid Build Coastguard Worker
1450*eb293b8fSAndroid Build Coastguard Worker // CIE 32.
1451*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x600, 0xfc);
1452*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x604, 0xffffffff);
1453*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
1454*eb293b8fSAndroid Build Coastguard Worker
1455*eb293b8fSAndroid Build Coastguard Worker // FDE 32.
1456*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x700, 0xfc);
1457*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x704, 0);
1458*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x708, 0x2100);
1459*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x70c, 0x200);
1460*eb293b8fSAndroid Build Coastguard Worker
1461*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1462*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1463*eb293b8fSAndroid Build Coastguard Worker elf->InitHeaders();
1464*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1465*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0));
1466*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x20ff));
1467*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x2100));
1468*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x2200));
1469*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x22ff));
1470*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x2300));
1471*eb293b8fSAndroid Build Coastguard Worker }
1472*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,is_valid_pc_from_eh_frame)1473*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1474*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterface> elf(new ElfInterface32(memory_));
1475*eb293b8fSAndroid Build Coastguard Worker
1476*eb293b8fSAndroid Build Coastguard Worker uint64_t sh_offset = 0x100;
1477*eb293b8fSAndroid Build Coastguard Worker
1478*eb293b8fSAndroid Build Coastguard Worker Elf32_Ehdr ehdr = {};
1479*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 1;
1480*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = sh_offset;
1481*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Elf32_Shdr);
1482*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1483*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1484*eb293b8fSAndroid Build Coastguard Worker
1485*eb293b8fSAndroid Build Coastguard Worker Elf32_Shdr shdr = {};
1486*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NULL;
1487*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1488*eb293b8fSAndroid Build Coastguard Worker
1489*eb293b8fSAndroid Build Coastguard Worker sh_offset += sizeof(shdr);
1490*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1491*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1492*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 1;
1493*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x500;
1494*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x100;
1495*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1496*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x500, ".eh_frame");
1497*eb293b8fSAndroid Build Coastguard Worker
1498*eb293b8fSAndroid Build Coastguard Worker sh_offset += sizeof(shdr);
1499*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1500*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_PROGBITS;
1501*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0;
1502*eb293b8fSAndroid Build Coastguard Worker shdr.sh_addr = 0x600;
1503*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0x600;
1504*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x200;
1505*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(sh_offset, &shdr, sizeof(shdr));
1506*eb293b8fSAndroid Build Coastguard Worker
1507*eb293b8fSAndroid Build Coastguard Worker // CIE 32.
1508*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x600, 0xfc);
1509*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x604, 0);
1510*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
1511*eb293b8fSAndroid Build Coastguard Worker
1512*eb293b8fSAndroid Build Coastguard Worker // FDE 32.
1513*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x700, 0xfc);
1514*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x704, 0x104);
1515*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x708, 0x20f8);
1516*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetData32(0x70c, 0x200);
1517*eb293b8fSAndroid Build Coastguard Worker
1518*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1519*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1520*eb293b8fSAndroid Build Coastguard Worker elf->InitHeaders();
1521*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0, load_bias);
1522*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0));
1523*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x27ff));
1524*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x2800));
1525*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x2900));
1526*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(elf->IsValidPc(0x29ff));
1527*eb293b8fSAndroid Build Coastguard Worker EXPECT_FALSE(elf->IsValidPc(0x2a00));
1528*eb293b8fSAndroid Build Coastguard Worker }
1529*eb293b8fSAndroid Build Coastguard Worker
1530*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildID()1531*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::BuildID() {
1532*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1533*eb293b8fSAndroid Build Coastguard Worker
1534*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
1535*eb293b8fSAndroid Build Coastguard Worker
1536*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1537*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
1538*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1539*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1540*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1541*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1542*eb293b8fSAndroid Build Coastguard Worker
1543*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1544*eb293b8fSAndroid Build Coastguard Worker
1545*eb293b8fSAndroid Build Coastguard Worker char note_section[128];
1546*eb293b8fSAndroid Build Coastguard Worker Nhdr note_header = {};
1547*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 4; // "GNU"
1548*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1549*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1550*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section, ¬e_header, sizeof(note_header));
1551*eb293b8fSAndroid Build Coastguard Worker size_t note_offset = sizeof(note_header);
1552*eb293b8fSAndroid Build Coastguard Worker // The note information contains the GNU and trailing '\0'.
1553*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1554*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof("GNU");
1555*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1556*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1557*eb293b8fSAndroid Build Coastguard Worker
1558*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1559*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
1560*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
1561*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
1562*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = sizeof(note_section);
1563*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1564*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1565*eb293b8fSAndroid Build Coastguard Worker
1566*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1567*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1568*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1569*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1570*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1571*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1572*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1573*eb293b8fSAndroid Build Coastguard Worker
1574*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1575*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xb000, note_section, sizeof(note_section));
1576*eb293b8fSAndroid Build Coastguard Worker
1577*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1578*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1579*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("BUILDID", elf->GetBuildID());
1580*eb293b8fSAndroid Build Coastguard Worker }
1581*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_32)1582*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_32) {
1583*eb293b8fSAndroid Build Coastguard Worker BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1584*eb293b8fSAndroid Build Coastguard Worker }
1585*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_64)1586*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_64) {
1587*eb293b8fSAndroid Build Coastguard Worker BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1588*eb293b8fSAndroid Build Coastguard Worker }
1589*eb293b8fSAndroid Build Coastguard Worker
1590*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDTwoNotes()1591*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::BuildIDTwoNotes() {
1592*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1593*eb293b8fSAndroid Build Coastguard Worker
1594*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
1595*eb293b8fSAndroid Build Coastguard Worker
1596*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1597*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
1598*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1599*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1600*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1601*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1602*eb293b8fSAndroid Build Coastguard Worker
1603*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1604*eb293b8fSAndroid Build Coastguard Worker
1605*eb293b8fSAndroid Build Coastguard Worker char note_section[128];
1606*eb293b8fSAndroid Build Coastguard Worker Nhdr note_header = {};
1607*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 8; // "WRONG" aligned to 4
1608*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1609*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1610*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section, ¬e_header, sizeof(note_header));
1611*eb293b8fSAndroid Build Coastguard Worker size_t note_offset = sizeof(note_header);
1612*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "WRONG", sizeof("WRONG"));
1613*eb293b8fSAndroid Build Coastguard Worker note_offset += 8;
1614*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1615*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1616*eb293b8fSAndroid Build Coastguard Worker note_offset += 8;
1617*eb293b8fSAndroid Build Coastguard Worker
1618*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 4; // "GNU"
1619*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1620*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1621*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], ¬e_header, sizeof(note_header));
1622*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof(note_header);
1623*eb293b8fSAndroid Build Coastguard Worker // The note information contains the GNU and trailing '\0'.
1624*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1625*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof("GNU");
1626*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1627*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1628*eb293b8fSAndroid Build Coastguard Worker
1629*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1630*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
1631*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
1632*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
1633*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = sizeof(note_section);
1634*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1635*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1636*eb293b8fSAndroid Build Coastguard Worker
1637*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1638*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1639*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1640*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1641*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1642*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1643*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1644*eb293b8fSAndroid Build Coastguard Worker
1645*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1646*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xb000, note_section, sizeof(note_section));
1647*eb293b8fSAndroid Build Coastguard Worker
1648*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1649*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1650*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("BUILDID", elf->GetBuildID());
1651*eb293b8fSAndroid Build Coastguard Worker }
1652*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_two_notes_32)1653*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_two_notes_32) {
1654*eb293b8fSAndroid Build Coastguard Worker BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1655*eb293b8fSAndroid Build Coastguard Worker }
1656*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_two_notes_64)1657*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_two_notes_64) {
1658*eb293b8fSAndroid Build Coastguard Worker BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1659*eb293b8fSAndroid Build Coastguard Worker }
1660*eb293b8fSAndroid Build Coastguard Worker
1661*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForName()1662*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1663*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1664*eb293b8fSAndroid Build Coastguard Worker
1665*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
1666*eb293b8fSAndroid Build Coastguard Worker
1667*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1668*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
1669*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1670*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1671*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1672*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1673*eb293b8fSAndroid Build Coastguard Worker
1674*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1675*eb293b8fSAndroid Build Coastguard Worker
1676*eb293b8fSAndroid Build Coastguard Worker char note_section[128];
1677*eb293b8fSAndroid Build Coastguard Worker Nhdr note_header = {};
1678*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 4; // "GNU"
1679*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1680*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1681*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section, ¬e_header, sizeof(note_header));
1682*eb293b8fSAndroid Build Coastguard Worker size_t note_offset = sizeof(note_header);
1683*eb293b8fSAndroid Build Coastguard Worker // The note information contains the GNU and trailing '\0'.
1684*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1685*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof("GNU");
1686*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1687*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1688*eb293b8fSAndroid Build Coastguard Worker
1689*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1690*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
1691*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
1692*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
1693*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = sizeof(note_header) + 1;
1694*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1695*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1696*eb293b8fSAndroid Build Coastguard Worker
1697*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1698*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1699*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1700*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1701*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1702*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1703*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1704*eb293b8fSAndroid Build Coastguard Worker
1705*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1706*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xb000, note_section, sizeof(note_section));
1707*eb293b8fSAndroid Build Coastguard Worker
1708*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1709*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1710*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetBuildID());
1711*eb293b8fSAndroid Build Coastguard Worker }
1712*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_name_32)1713*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_32) {
1714*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1715*eb293b8fSAndroid Build Coastguard Worker }
1716*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_name_64)1717*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_64) {
1718*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1719*eb293b8fSAndroid Build Coastguard Worker }
1720*eb293b8fSAndroid Build Coastguard Worker
1721*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForDesc()1722*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1723*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1724*eb293b8fSAndroid Build Coastguard Worker
1725*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
1726*eb293b8fSAndroid Build Coastguard Worker
1727*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1728*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
1729*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1730*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1731*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1732*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1733*eb293b8fSAndroid Build Coastguard Worker
1734*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1735*eb293b8fSAndroid Build Coastguard Worker
1736*eb293b8fSAndroid Build Coastguard Worker char note_section[128];
1737*eb293b8fSAndroid Build Coastguard Worker Nhdr note_header = {};
1738*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 4; // "GNU"
1739*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1740*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1741*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section, ¬e_header, sizeof(note_header));
1742*eb293b8fSAndroid Build Coastguard Worker size_t note_offset = sizeof(note_header);
1743*eb293b8fSAndroid Build Coastguard Worker // The note information contains the GNU and trailing '\0'.
1744*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1745*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof("GNU");
1746*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1747*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1748*eb293b8fSAndroid Build Coastguard Worker
1749*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1750*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
1751*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
1752*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
1753*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1754*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1755*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1756*eb293b8fSAndroid Build Coastguard Worker
1757*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1758*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1759*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1760*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1761*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1762*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1763*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1764*eb293b8fSAndroid Build Coastguard Worker
1765*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1766*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xb000, note_section, sizeof(note_section));
1767*eb293b8fSAndroid Build Coastguard Worker
1768*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1769*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1770*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetBuildID());
1771*eb293b8fSAndroid Build Coastguard Worker }
1772*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_desc_32)1773*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_32) {
1774*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1775*eb293b8fSAndroid Build Coastguard Worker }
1776*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_desc_64)1777*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_64) {
1778*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1779*eb293b8fSAndroid Build Coastguard Worker }
1780*eb293b8fSAndroid Build Coastguard Worker
1781*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForHeader()1782*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1783*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1784*eb293b8fSAndroid Build Coastguard Worker
1785*eb293b8fSAndroid Build Coastguard Worker uint64_t offset = 0x2000;
1786*eb293b8fSAndroid Build Coastguard Worker
1787*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1788*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shoff = offset;
1789*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shnum = 3;
1790*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shentsize = sizeof(Shdr);
1791*eb293b8fSAndroid Build Coastguard Worker ehdr.e_shstrndx = 2;
1792*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1793*eb293b8fSAndroid Build Coastguard Worker
1794*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1795*eb293b8fSAndroid Build Coastguard Worker
1796*eb293b8fSAndroid Build Coastguard Worker char note_section[128];
1797*eb293b8fSAndroid Build Coastguard Worker Nhdr note_header = {};
1798*eb293b8fSAndroid Build Coastguard Worker note_header.n_namesz = 4; // "GNU"
1799*eb293b8fSAndroid Build Coastguard Worker note_header.n_descsz = 7; // "BUILDID"
1800*eb293b8fSAndroid Build Coastguard Worker note_header.n_type = NT_GNU_BUILD_ID;
1801*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section, ¬e_header, sizeof(note_header));
1802*eb293b8fSAndroid Build Coastguard Worker size_t note_offset = sizeof(note_header);
1803*eb293b8fSAndroid Build Coastguard Worker // The note information contains the GNU and trailing '\0'.
1804*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1805*eb293b8fSAndroid Build Coastguard Worker note_offset += sizeof("GNU");
1806*eb293b8fSAndroid Build Coastguard Worker // This part of the note does not contain any trailing '\0'.
1807*eb293b8fSAndroid Build Coastguard Worker memcpy(¬e_section[note_offset], "BUILDID", 7);
1808*eb293b8fSAndroid Build Coastguard Worker
1809*eb293b8fSAndroid Build Coastguard Worker Shdr shdr = {};
1810*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_NOTE;
1811*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x500;
1812*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xb000;
1813*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = sizeof(note_header) - 1;
1814*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1815*eb293b8fSAndroid Build Coastguard Worker offset += ehdr.e_shentsize;
1816*eb293b8fSAndroid Build Coastguard Worker
1817*eb293b8fSAndroid Build Coastguard Worker // The string data for section header names.
1818*eb293b8fSAndroid Build Coastguard Worker memset(&shdr, 0, sizeof(shdr));
1819*eb293b8fSAndroid Build Coastguard Worker shdr.sh_type = SHT_STRTAB;
1820*eb293b8fSAndroid Build Coastguard Worker shdr.sh_name = 0x20000;
1821*eb293b8fSAndroid Build Coastguard Worker shdr.sh_offset = 0xf000;
1822*eb293b8fSAndroid Build Coastguard Worker shdr.sh_size = 0x1000;
1823*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(offset, &shdr, sizeof(shdr));
1824*eb293b8fSAndroid Build Coastguard Worker
1825*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1826*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0xb000, note_section, sizeof(note_section));
1827*eb293b8fSAndroid Build Coastguard Worker
1828*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias = 0;
1829*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&load_bias));
1830*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ("", elf->GetBuildID());
1831*eb293b8fSAndroid Build Coastguard Worker }
1832*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_header_32)1833*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_32) {
1834*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1835*eb293b8fSAndroid Build Coastguard Worker }
1836*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_header_64)1837*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_64) {
1838*eb293b8fSAndroid Build Coastguard Worker BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1839*eb293b8fSAndroid Build Coastguard Worker }
1840*eb293b8fSAndroid Build Coastguard Worker
1841*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckLoadBiasInFirstPhdr(int64_t load_bias)1842*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(int64_t load_bias) {
1843*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1844*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
1845*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 2;
1846*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
1847*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1848*eb293b8fSAndroid Build Coastguard Worker
1849*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
1850*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1851*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0;
1852*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = load_bias;
1853*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
1854*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1855*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1856*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
1857*eb293b8fSAndroid Build Coastguard Worker
1858*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
1859*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1860*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x1000;
1861*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x2000;
1862*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1863*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1864*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1865*eb293b8fSAndroid Build Coastguard Worker
1866*eb293b8fSAndroid Build Coastguard Worker int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(memory_.get());
1867*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(load_bias, static_load_bias);
1868*eb293b8fSAndroid Build Coastguard Worker
1869*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1870*eb293b8fSAndroid Build Coastguard Worker int64_t init_load_bias = 0;
1871*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&init_load_bias));
1872*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(init_load_bias, static_load_bias);
1873*eb293b8fSAndroid Build Coastguard Worker }
1874*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_zero_32)1875*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_zero_32) {
1876*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0);
1877*eb293b8fSAndroid Build Coastguard Worker }
1878*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_zero_64)1879*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_zero_64) {
1880*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0);
1881*eb293b8fSAndroid Build Coastguard Worker }
1882*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_non_zero_32)1883*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_non_zero_32) {
1884*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000);
1885*eb293b8fSAndroid Build Coastguard Worker }
1886*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_non_zero_64)1887*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_non_zero_64) {
1888*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000);
1889*eb293b8fSAndroid Build Coastguard Worker }
1890*eb293b8fSAndroid Build Coastguard Worker
1891*eb293b8fSAndroid Build Coastguard Worker template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckLoadBiasInFirstExecPhdr(uint64_t offset,uint64_t vaddr,int64_t load_bias)1892*eb293b8fSAndroid Build Coastguard Worker void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr,
1893*eb293b8fSAndroid Build Coastguard Worker int64_t load_bias) {
1894*eb293b8fSAndroid Build Coastguard Worker Ehdr ehdr = {};
1895*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phoff = 0x100;
1896*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phnum = 3;
1897*eb293b8fSAndroid Build Coastguard Worker ehdr.e_phentsize = sizeof(Phdr);
1898*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0, &ehdr, sizeof(ehdr));
1899*eb293b8fSAndroid Build Coastguard Worker
1900*eb293b8fSAndroid Build Coastguard Worker Phdr phdr = {};
1901*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1902*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x10000;
1903*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R;
1904*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1905*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100, &phdr, sizeof(phdr));
1906*eb293b8fSAndroid Build Coastguard Worker
1907*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
1908*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1909*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = offset;
1910*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = vaddr;
1911*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x2000;
1912*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1913*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1914*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1915*eb293b8fSAndroid Build Coastguard Worker
1916*eb293b8fSAndroid Build Coastguard Worker // Second executable load should be ignored for load bias computation.
1917*eb293b8fSAndroid Build Coastguard Worker memset(&phdr, 0, sizeof(phdr));
1918*eb293b8fSAndroid Build Coastguard Worker phdr.p_type = PT_LOAD;
1919*eb293b8fSAndroid Build Coastguard Worker phdr.p_offset = 0x1234;
1920*eb293b8fSAndroid Build Coastguard Worker phdr.p_vaddr = 0x2000;
1921*eb293b8fSAndroid Build Coastguard Worker phdr.p_memsz = 0x2000;
1922*eb293b8fSAndroid Build Coastguard Worker phdr.p_flags = PF_R | PF_X;
1923*eb293b8fSAndroid Build Coastguard Worker phdr.p_align = 0x1000;
1924*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x200 + sizeof(phdr), &phdr, sizeof(phdr));
1925*eb293b8fSAndroid Build Coastguard Worker
1926*eb293b8fSAndroid Build Coastguard Worker int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(memory_.get());
1927*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(load_bias, static_load_bias);
1928*eb293b8fSAndroid Build Coastguard Worker
1929*eb293b8fSAndroid Build Coastguard Worker std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(memory_));
1930*eb293b8fSAndroid Build Coastguard Worker int64_t init_load_bias = 0;
1931*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf->Init(&init_load_bias));
1932*eb293b8fSAndroid Build Coastguard Worker ASSERT_EQ(init_load_bias, static_load_bias);
1933*eb293b8fSAndroid Build Coastguard Worker }
1934*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_zero_32)1935*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_32) {
1936*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x1000, 0);
1937*eb293b8fSAndroid Build Coastguard Worker }
1938*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_zero_64)1939*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_64) {
1940*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x1000, 0);
1941*eb293b8fSAndroid Build Coastguard Worker }
1942*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_positive_32)1943*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_32) {
1944*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x4000, 0x3000);
1945*eb293b8fSAndroid Build Coastguard Worker }
1946*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_positive_64)1947*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_64) {
1948*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x4000, 0x3000);
1949*eb293b8fSAndroid Build Coastguard Worker }
1950*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_negative_32)1951*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_32) {
1952*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, -0x4000);
1953*eb293b8fSAndroid Build Coastguard Worker }
1954*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,get_load_bias_exec_negative_64)1955*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_64) {
1956*eb293b8fSAndroid Build Coastguard Worker CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, -0x4000);
1957*eb293b8fSAndroid Build Coastguard Worker }
1958*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,huge_gnu_debugdata_size)1959*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, huge_gnu_debugdata_size) {
1960*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> empty;
1961*eb293b8fSAndroid Build Coastguard Worker ElfInterfaceFake interface(empty);
1962*eb293b8fSAndroid Build Coastguard Worker
1963*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetGnuDebugdataOffset(0x1000);
1964*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetGnuDebugdataSize(0xffffffffffffffffUL);
1965*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1966*eb293b8fSAndroid Build Coastguard Worker
1967*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetGnuDebugdataSize(0x4000000000000UL);
1968*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1969*eb293b8fSAndroid Build Coastguard Worker
1970*eb293b8fSAndroid Build Coastguard Worker // This should exceed the size_t value of the first allocation.
1971*eb293b8fSAndroid Build Coastguard Worker #if defined(__LP64__)
1972*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetGnuDebugdataSize(0x3333333333333334ULL);
1973*eb293b8fSAndroid Build Coastguard Worker #else
1974*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetGnuDebugdataSize(0x33333334);
1975*eb293b8fSAndroid Build Coastguard Worker #endif
1976*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1977*eb293b8fSAndroid Build Coastguard Worker }
1978*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,compressed_eh_frames)1979*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, compressed_eh_frames) {
1980*eb293b8fSAndroid Build Coastguard Worker SectionInfo eh_hdr_info = {.offset = 0x1000};
1981*eb293b8fSAndroid Build Coastguard Worker uint8_t data[5] = {/*version*/ 1, /*ptr_encoding DW_EH_PE_omit*/ 0xff,
1982*eb293b8fSAndroid Build Coastguard Worker /*fde_count_encoding DW_EH_PE_udata1*/ 0xd,
1983*eb293b8fSAndroid Build Coastguard Worker /*table_encoding DW_EH_PE_absptr*/ 0, /*fde_count*/ 1};
1984*eb293b8fSAndroid Build Coastguard Worker fake_memory_->SetMemory(0x1000, data, sizeof(data));
1985*eb293b8fSAndroid Build Coastguard Worker SectionInfo eh_info = {.offset = 0x2000};
1986*eb293b8fSAndroid Build Coastguard Worker
1987*eb293b8fSAndroid Build Coastguard Worker // Verify that the eh_frame and eh_frame_hdr are created properly.
1988*eb293b8fSAndroid Build Coastguard Worker ElfInterface32Fake interface(memory_);
1989*eb293b8fSAndroid Build Coastguard Worker eh_hdr_info.flags = 0;
1990*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetEhFrameHdrInfo(eh_hdr_info);
1991*eb293b8fSAndroid Build Coastguard Worker eh_info.flags = 0;
1992*eb293b8fSAndroid Build Coastguard Worker interface.FakeSetEhFrameInfo(eh_info);
1993*eb293b8fSAndroid Build Coastguard Worker interface.InitHeaders();
1994*eb293b8fSAndroid Build Coastguard Worker EXPECT_NE(0U, interface.eh_frame_hdr_info().offset);
1995*eb293b8fSAndroid Build Coastguard Worker EXPECT_NE(0U, interface.eh_frame_info().offset);
1996*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(interface.eh_frame() != nullptr);
1997*eb293b8fSAndroid Build Coastguard Worker
1998*eb293b8fSAndroid Build Coastguard Worker // Init setting SHF_COMPRESSED for both sections, both should fail to init.
1999*eb293b8fSAndroid Build Coastguard Worker ElfInterface32Fake interface_both(memory_);
2000*eb293b8fSAndroid Build Coastguard Worker eh_hdr_info.flags = 0x800;
2001*eb293b8fSAndroid Build Coastguard Worker interface_both.FakeSetEhFrameHdrInfo(eh_hdr_info);
2002*eb293b8fSAndroid Build Coastguard Worker eh_info.flags = 0x800;
2003*eb293b8fSAndroid Build Coastguard Worker interface_both.FakeSetEhFrameInfo(eh_info);
2004*eb293b8fSAndroid Build Coastguard Worker interface_both.InitHeaders();
2005*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, interface_both.eh_frame_hdr_info().offset);
2006*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, interface_both.eh_frame_info().offset);
2007*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(interface_both.eh_frame() == nullptr);
2008*eb293b8fSAndroid Build Coastguard Worker
2009*eb293b8fSAndroid Build Coastguard Worker // Init setting SHF_COMPRESSED for only the eh_frame_hdr, eh_frame should init.
2010*eb293b8fSAndroid Build Coastguard Worker ElfInterface32Fake interface_hdr(memory_);
2011*eb293b8fSAndroid Build Coastguard Worker eh_hdr_info.flags = 0x800;
2012*eb293b8fSAndroid Build Coastguard Worker interface_hdr.FakeSetEhFrameHdrInfo(eh_hdr_info);
2013*eb293b8fSAndroid Build Coastguard Worker eh_info.flags = 0;
2014*eb293b8fSAndroid Build Coastguard Worker interface_hdr.FakeSetEhFrameInfo(eh_info);
2015*eb293b8fSAndroid Build Coastguard Worker interface_hdr.InitHeaders();
2016*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, interface_hdr.eh_frame_hdr_info().offset);
2017*eb293b8fSAndroid Build Coastguard Worker EXPECT_NE(0U, interface_hdr.eh_frame_info().offset);
2018*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(interface_hdr.eh_frame() != nullptr);
2019*eb293b8fSAndroid Build Coastguard Worker
2020*eb293b8fSAndroid Build Coastguard Worker // Init setting SHF_COMPRESSED for only the eh_frame, both should fail to init.
2021*eb293b8fSAndroid Build Coastguard Worker ElfInterface32Fake interface_eh(memory_);
2022*eb293b8fSAndroid Build Coastguard Worker eh_hdr_info.flags = 0;
2023*eb293b8fSAndroid Build Coastguard Worker interface_eh.FakeSetEhFrameHdrInfo(eh_hdr_info);
2024*eb293b8fSAndroid Build Coastguard Worker eh_info.flags = 0x800;
2025*eb293b8fSAndroid Build Coastguard Worker interface_eh.FakeSetEhFrameInfo(eh_info);
2026*eb293b8fSAndroid Build Coastguard Worker interface_eh.InitHeaders();
2027*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, interface_eh.eh_frame_hdr_info().offset);
2028*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, interface_eh.eh_frame_info().offset);
2029*eb293b8fSAndroid Build Coastguard Worker EXPECT_TRUE(interface_eh.eh_frame() == nullptr);
2030*eb293b8fSAndroid Build Coastguard Worker }
2031*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,compressed_debug_frame_fde_verify)2032*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, compressed_debug_frame_fde_verify) {
2033*eb293b8fSAndroid Build Coastguard Worker std::string lib_dir = TestGetFileDirectory() + "libs/";
2034*eb293b8fSAndroid Build Coastguard Worker auto elf_memory = Memory::CreateFileMemory(lib_dir + "libc.so", 0);
2035*eb293b8fSAndroid Build Coastguard Worker Elf elf(elf_memory);
2036*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.Init());
2037*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.valid());
2038*eb293b8fSAndroid Build Coastguard Worker auto section = elf.interface()->debug_frame();
2039*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(section != nullptr);
2040*eb293b8fSAndroid Build Coastguard Worker
2041*eb293b8fSAndroid Build Coastguard Worker elf_memory = Memory::CreateFileMemory(lib_dir + "libc_zlib.so", 0);
2042*eb293b8fSAndroid Build Coastguard Worker Elf elf_zlib(elf_memory);
2043*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf_zlib.Init());
2044*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf_zlib.valid());
2045*eb293b8fSAndroid Build Coastguard Worker auto section_zlib = elf_zlib.interface()->debug_frame();
2046*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(section_zlib != nullptr);
2047*eb293b8fSAndroid Build Coastguard Worker
2048*eb293b8fSAndroid Build Coastguard Worker elf_memory = Memory::CreateFileMemory(lib_dir + "libc_zstd.so", 0);
2049*eb293b8fSAndroid Build Coastguard Worker Elf elf_zstd(elf_memory);
2050*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf_zstd.Init());
2051*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf_zstd.valid());
2052*eb293b8fSAndroid Build Coastguard Worker auto section_zstd = elf_zstd.interface()->debug_frame();
2053*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(section_zstd != nullptr);
2054*eb293b8fSAndroid Build Coastguard Worker
2055*eb293b8fSAndroid Build Coastguard Worker auto iter = section->begin();
2056*eb293b8fSAndroid Build Coastguard Worker auto iter_zlib = section_zlib->begin();
2057*eb293b8fSAndroid Build Coastguard Worker auto iter_zstd = section_zstd->begin();
2058*eb293b8fSAndroid Build Coastguard Worker
2059*eb293b8fSAndroid Build Coastguard Worker // Check that all of the fdes are in the same order, and contain the same data.
2060*eb293b8fSAndroid Build Coastguard Worker size_t total_fdes = 0;
2061*eb293b8fSAndroid Build Coastguard Worker while (iter != section->end() && iter_zlib != section_zlib->end() &&
2062*eb293b8fSAndroid Build Coastguard Worker iter_zstd != section_zstd->end()) {
2063*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(iter != section->end());
2064*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(iter_zlib != section_zlib->end());
2065*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(iter_zstd != section_zstd->end());
2066*eb293b8fSAndroid Build Coastguard Worker auto fde = *iter;
2067*eb293b8fSAndroid Build Coastguard Worker auto fde_zlib = *iter_zlib;
2068*eb293b8fSAndroid Build Coastguard Worker auto fde_zstd = *iter_zstd;
2069*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cie_offset, fde_zlib->cie_offset);
2070*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cie_offset, fde_zstd->cie_offset);
2071*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cfa_instructions_offset, fde_zlib->cfa_instructions_offset);
2072*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cfa_instructions_offset, fde_zstd->cfa_instructions_offset);
2073*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cfa_instructions_end, fde_zlib->cfa_instructions_end);
2074*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->cfa_instructions_end, fde_zstd->cfa_instructions_end);
2075*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->pc_start, fde_zlib->pc_start);
2076*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->pc_start, fde_zstd->pc_start);
2077*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->pc_end, fde_zlib->pc_end);
2078*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->pc_end, fde_zstd->pc_end);
2079*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->lsda_address, fde_zlib->lsda_address);
2080*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(fde->lsda_address, fde_zstd->lsda_address);
2081*eb293b8fSAndroid Build Coastguard Worker ++iter;
2082*eb293b8fSAndroid Build Coastguard Worker ++iter_zlib;
2083*eb293b8fSAndroid Build Coastguard Worker ++iter_zstd;
2084*eb293b8fSAndroid Build Coastguard Worker ++total_fdes;
2085*eb293b8fSAndroid Build Coastguard Worker }
2086*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(2320U, total_fdes);
2087*eb293b8fSAndroid Build Coastguard Worker }
2088*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,compressed_debug_frame_from_memory)2089*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, compressed_debug_frame_from_memory) {
2090*eb293b8fSAndroid Build Coastguard Worker std::string lib_dir = TestGetFileDirectory() + "libs/";
2091*eb293b8fSAndroid Build Coastguard Worker android::base::unique_fd fd(
2092*eb293b8fSAndroid Build Coastguard Worker TEMP_FAILURE_RETRY(open((lib_dir + "libc_zstd.so").c_str(), O_RDONLY | O_CLOEXEC)));
2093*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(-1, fd);
2094*eb293b8fSAndroid Build Coastguard Worker struct stat buf;
2095*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(-1, fstat(fd, &buf));
2096*eb293b8fSAndroid Build Coastguard Worker void* map_addr = mmap(nullptr, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
2097*eb293b8fSAndroid Build Coastguard Worker ASSERT_NE(MAP_FAILED, map_addr);
2098*eb293b8fSAndroid Build Coastguard Worker auto process_memory = Memory::CreateProcessMemory(getpid());
2099*eb293b8fSAndroid Build Coastguard Worker std::shared_ptr<Memory> elf_memory(
2100*eb293b8fSAndroid Build Coastguard Worker new MemoryRange(process_memory, reinterpret_cast<uint64_t>(map_addr), buf.st_size, 0));
2101*eb293b8fSAndroid Build Coastguard Worker
2102*eb293b8fSAndroid Build Coastguard Worker Elf elf(elf_memory);
2103*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.Init());
2104*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.valid());
2105*eb293b8fSAndroid Build Coastguard Worker auto section = elf.interface()->debug_frame();
2106*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(section != nullptr);
2107*eb293b8fSAndroid Build Coastguard Worker
2108*eb293b8fSAndroid Build Coastguard Worker // Don't check all of the fdes, just verify the first one.
2109*eb293b8fSAndroid Build Coastguard Worker std::vector<const DwarfFde*> fdes;
2110*eb293b8fSAndroid Build Coastguard Worker section->GetFdes(&fdes);
2111*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x9309cU, fdes[0]->cie_offset);
2112*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x930c0U, fdes[0]->cfa_instructions_offset);
2113*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0x930c0U, fdes[0]->cfa_instructions_end);
2114*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, fdes[0]->pc_start);
2115*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(2U, fdes[0]->pc_end);
2116*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(0U, fdes[0]->lsda_address);
2117*eb293b8fSAndroid Build Coastguard Worker EXPECT_EQ(2320U, fdes.size());
2118*eb293b8fSAndroid Build Coastguard Worker
2119*eb293b8fSAndroid Build Coastguard Worker munmap(map_addr, buf.st_size);
2120*eb293b8fSAndroid Build Coastguard Worker }
2121*eb293b8fSAndroid Build Coastguard Worker
TEST_F(ElfInterfaceTest,bad_compressed_debug_frame)2122*eb293b8fSAndroid Build Coastguard Worker TEST_F(ElfInterfaceTest, bad_compressed_debug_frame) {
2123*eb293b8fSAndroid Build Coastguard Worker std::string lib_dir = TestGetFileDirectory() + "libs/";
2124*eb293b8fSAndroid Build Coastguard Worker auto elf_memory = Memory::CreateFileMemory(TestGetFileDirectory() + "libs/elf_bad_compress", 0);
2125*eb293b8fSAndroid Build Coastguard Worker Elf elf(elf_memory);
2126*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.Init());
2127*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.valid());
2128*eb293b8fSAndroid Build Coastguard Worker // This elf file has a compressed debug frame, but it's bad compress data.
2129*eb293b8fSAndroid Build Coastguard Worker ASSERT_TRUE(elf.interface()->debug_frame() == nullptr);
2130*eb293b8fSAndroid Build Coastguard Worker }
2131*eb293b8fSAndroid Build Coastguard Worker
2132*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack
2133