ElfTest.cpp revision 570b76f04fbca11471738319f8e9ca0bb5682182
1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <elf.h>
18#include <fcntl.h>
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <unistd.h>
22
23#include <gtest/gtest.h>
24
25#include "Elf.h"
26
27#include "ElfTestUtils.h"
28#include "MemoryFake.h"
29
30#if !defined(PT_ARM_EXIDX)
31#define PT_ARM_EXIDX 0x70000001
32#endif
33
34class ElfTest : public ::testing::Test {
35 protected:
36  void SetUp() override {
37    memory_ = new MemoryFake;
38  }
39
40  void InitElf32(uint32_t machine_type) {
41    Elf32_Ehdr ehdr;
42    TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, machine_type);
43
44    ehdr.e_phoff = 0x100;
45    ehdr.e_ehsize = sizeof(ehdr);
46    ehdr.e_phentsize = sizeof(Elf32_Phdr);
47    ehdr.e_phnum = 1;
48    ehdr.e_shentsize = sizeof(Elf32_Shdr);
49    if (machine_type == EM_ARM) {
50      ehdr.e_flags = 0x5000200;
51      ehdr.e_phnum = 2;
52    }
53    memory_->SetMemory(0, &ehdr, sizeof(ehdr));
54
55    Elf32_Phdr phdr;
56    memset(&phdr, 0, sizeof(phdr));
57    phdr.p_type = PT_LOAD;
58    phdr.p_filesz = 0x10000;
59    phdr.p_memsz = 0x10000;
60    phdr.p_flags = PF_R | PF_X;
61    phdr.p_align = 0x1000;
62    memory_->SetMemory(0x100, &phdr, sizeof(phdr));
63
64    if (machine_type == EM_ARM) {
65      memset(&phdr, 0, sizeof(phdr));
66      phdr.p_type = PT_ARM_EXIDX;
67      phdr.p_offset = 0x30000;
68      phdr.p_vaddr = 0x30000;
69      phdr.p_paddr = 0x30000;
70      phdr.p_filesz = 16;
71      phdr.p_memsz = 16;
72      phdr.p_flags = PF_R;
73      phdr.p_align = 0x4;
74      memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
75    }
76  }
77
78  void InitElf64(uint32_t machine_type) {
79    Elf64_Ehdr ehdr;
80    TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, machine_type);
81
82    ehdr.e_phoff = 0x100;
83    ehdr.e_flags = 0x5000200;
84    ehdr.e_ehsize = sizeof(ehdr);
85    ehdr.e_phentsize = sizeof(Elf64_Phdr);
86    ehdr.e_phnum = 1;
87    ehdr.e_shentsize = sizeof(Elf64_Shdr);
88    memory_->SetMemory(0, &ehdr, sizeof(ehdr));
89
90    Elf64_Phdr phdr;
91    memset(&phdr, 0, sizeof(phdr));
92    phdr.p_type = PT_LOAD;
93    phdr.p_filesz = 0x10000;
94    phdr.p_memsz = 0x10000;
95    phdr.p_flags = PF_R | PF_X;
96    phdr.p_align = 0x1000;
97    memory_->SetMemory(0x100, &phdr, sizeof(phdr));
98  }
99
100  MemoryFake* memory_;
101};
102
103TEST_F(ElfTest, invalid_memory) {
104  Elf elf(memory_);
105
106  ASSERT_FALSE(elf.Init());
107  ASSERT_FALSE(elf.valid());
108}
109
110TEST_F(ElfTest, elf_invalid) {
111  Elf elf(memory_);
112
113  InitElf32(EM_386);
114
115  // Corrupt the ELF signature.
116  memory_->SetData32(0, 0x7f000000);
117
118  ASSERT_FALSE(elf.Init());
119  ASSERT_FALSE(elf.valid());
120  ASSERT_TRUE(elf.interface() == nullptr);
121
122  std::string name;
123  ASSERT_FALSE(elf.GetSoname(&name));
124
125  uint64_t func_offset;
126  ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset));
127
128  ASSERT_FALSE(elf.Step(0, nullptr, nullptr));
129}
130
131TEST_F(ElfTest, elf_arm) {
132  Elf elf(memory_);
133
134  InitElf32(EM_ARM);
135
136  ASSERT_TRUE(elf.Init());
137  ASSERT_TRUE(elf.valid());
138  ASSERT_EQ(static_cast<uint32_t>(EM_ARM), elf.machine_type());
139  ASSERT_EQ(ELFCLASS32, elf.class_type());
140  ASSERT_TRUE(elf.interface() != nullptr);
141}
142
143TEST_F(ElfTest, elf_x86) {
144  Elf elf(memory_);
145
146  InitElf32(EM_386);
147
148  ASSERT_TRUE(elf.Init());
149  ASSERT_TRUE(elf.valid());
150  ASSERT_EQ(static_cast<uint32_t>(EM_386), elf.machine_type());
151  ASSERT_EQ(ELFCLASS32, elf.class_type());
152  ASSERT_TRUE(elf.interface() != nullptr);
153}
154
155TEST_F(ElfTest, elf_arm64) {
156  Elf elf(memory_);
157
158  InitElf64(EM_AARCH64);
159
160  ASSERT_TRUE(elf.Init());
161  ASSERT_TRUE(elf.valid());
162  ASSERT_EQ(static_cast<uint32_t>(EM_AARCH64), elf.machine_type());
163  ASSERT_EQ(ELFCLASS64, elf.class_type());
164  ASSERT_TRUE(elf.interface() != nullptr);
165}
166
167TEST_F(ElfTest, elf_x86_64) {
168  Elf elf(memory_);
169
170  InitElf64(EM_X86_64);
171
172  ASSERT_TRUE(elf.Init());
173  ASSERT_TRUE(elf.valid());
174  ASSERT_EQ(static_cast<uint32_t>(EM_X86_64), elf.machine_type());
175  ASSERT_EQ(ELFCLASS64, elf.class_type());
176  ASSERT_TRUE(elf.interface() != nullptr);
177}
178
179TEST_F(ElfTest, gnu_debugdata_init_fail32) {
180  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, false,
181                                               [&](uint64_t offset, const void* ptr, size_t size) {
182                                                 memory_->SetMemory(offset, ptr, size);
183                                               });
184
185  Elf elf(memory_);
186  ASSERT_TRUE(elf.Init());
187  ASSERT_TRUE(elf.interface() != nullptr);
188  ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
189  EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
190  EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size());
191}
192
193TEST_F(ElfTest, gnu_debugdata_init_fail64) {
194  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, false,
195                                               [&](uint64_t offset, const void* ptr, size_t size) {
196                                                 memory_->SetMemory(offset, ptr, size);
197                                               });
198
199  Elf elf(memory_);
200  ASSERT_TRUE(elf.Init());
201  ASSERT_TRUE(elf.interface() != nullptr);
202  ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
203  EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
204  EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size());
205}
206
207TEST_F(ElfTest, gnu_debugdata_init32) {
208  TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true,
209                                               [&](uint64_t offset, const void* ptr, size_t size) {
210                                                 memory_->SetMemory(offset, ptr, size);
211                                               });
212
213  Elf elf(memory_);
214  ASSERT_TRUE(elf.Init());
215  ASSERT_TRUE(elf.interface() != nullptr);
216  ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
217  EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset());
218  EXPECT_EQ(0x8cU, elf.interface()->gnu_debugdata_size());
219
220  elf.InitGnuDebugdata();
221  ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
222}
223
224TEST_F(ElfTest, gnu_debugdata_init64) {
225  TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true,
226                                               [&](uint64_t offset, const void* ptr, size_t size) {
227                                                 memory_->SetMemory(offset, ptr, size);
228                                               });
229
230  Elf elf(memory_);
231  ASSERT_TRUE(elf.Init());
232  ASSERT_TRUE(elf.interface() != nullptr);
233  ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
234  EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset());
235  EXPECT_EQ(0x90U, elf.interface()->gnu_debugdata_size());
236
237  elf.InitGnuDebugdata();
238  ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
239}
240