blob: 25fec8e3adeca9f80c1e3e411e8d4b71ba993fa7 [file] [log] [blame]
Christopher Ferris3958f802017-02-01 15:44:40 -08001/*
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
19#include <gtest/gtest.h>
20
21#include "Elf.h"
22
23#include "MemoryFake.h"
24
25#if !defined(PT_ARM_EXIDX)
26#define PT_ARM_EXIDX 0x70000001
27#endif
28
29#if !defined(EM_AARCH64)
30#define EM_AARCH64 183
31#endif
32
33class ElfTest : public ::testing::Test {
34 protected:
35 void SetUp() override {
36 memory_ = new MemoryFake;
37 }
38
39 template <typename Ehdr>
40 void InitEhdr(Ehdr* ehdr) {
41 memset(ehdr, 0, sizeof(Ehdr));
42 memcpy(&ehdr->e_ident[0], ELFMAG, SELFMAG);
43 ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
44 ehdr->e_ident[EI_VERSION] = EV_CURRENT;
45 ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
46 }
47
48 void InitElf32(uint32_t type) {
49 Elf32_Ehdr ehdr;
50
51 InitEhdr<Elf32_Ehdr>(&ehdr);
52 ehdr.e_ident[EI_CLASS] = ELFCLASS32;
53
54 ehdr.e_type = ET_DYN;
55 ehdr.e_machine = type;
56 ehdr.e_version = EV_CURRENT;
57 ehdr.e_entry = 0;
58 ehdr.e_phoff = 0x100;
59 ehdr.e_shoff = 0;
60 ehdr.e_flags = 0;
61 ehdr.e_ehsize = sizeof(ehdr);
62 ehdr.e_phentsize = sizeof(Elf32_Phdr);
63 ehdr.e_phnum = 1;
64 ehdr.e_shentsize = sizeof(Elf32_Shdr);
65 ehdr.e_shnum = 0;
66 ehdr.e_shstrndx = 0;
67 if (type == EM_ARM) {
68 ehdr.e_flags = 0x5000200;
69 ehdr.e_phnum = 2;
70 }
71 memory_->SetMemory(0, &ehdr, sizeof(ehdr));
72
73 Elf32_Phdr phdr;
74 memset(&phdr, 0, sizeof(phdr));
75 phdr.p_type = PT_LOAD;
76 phdr.p_offset = 0;
77 phdr.p_vaddr = 0;
78 phdr.p_paddr = 0;
79 phdr.p_filesz = 0x10000;
80 phdr.p_memsz = 0x10000;
81 phdr.p_flags = PF_R | PF_X;
82 phdr.p_align = 0x1000;
83 memory_->SetMemory(0x100, &phdr, sizeof(phdr));
84
85 if (type == EM_ARM) {
86 memset(&phdr, 0, sizeof(phdr));
87 phdr.p_type = PT_ARM_EXIDX;
88 phdr.p_offset = 0x30000;
89 phdr.p_vaddr = 0x30000;
90 phdr.p_paddr = 0x30000;
91 phdr.p_filesz = 16;
92 phdr.p_memsz = 16;
93 phdr.p_flags = PF_R;
94 phdr.p_align = 0x4;
95 memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
96 }
97 }
98
99 void InitElf64(uint32_t type) {
100 Elf64_Ehdr ehdr;
101
102 InitEhdr<Elf64_Ehdr>(&ehdr);
103 ehdr.e_ident[EI_CLASS] = ELFCLASS64;
104
105 ehdr.e_type = ET_DYN;
106 ehdr.e_machine = type;
107 ehdr.e_version = EV_CURRENT;
108 ehdr.e_entry = 0;
109 ehdr.e_phoff = 0x100;
110 ehdr.e_shoff = 0;
111 ehdr.e_flags = 0x5000200;
112 ehdr.e_ehsize = sizeof(ehdr);
113 ehdr.e_phentsize = sizeof(Elf64_Phdr);
114 ehdr.e_phnum = 1;
115 ehdr.e_shentsize = sizeof(Elf64_Shdr);
116 ehdr.e_shnum = 0;
117 ehdr.e_shstrndx = 0;
118 memory_->SetMemory(0, &ehdr, sizeof(ehdr));
119
120 Elf64_Phdr phdr;
121 memset(&phdr, 0, sizeof(phdr));
122 phdr.p_type = PT_LOAD;
123 phdr.p_offset = 0;
124 phdr.p_vaddr = 0;
125 phdr.p_paddr = 0;
126 phdr.p_filesz = 0x10000;
127 phdr.p_memsz = 0x10000;
128 phdr.p_flags = PF_R | PF_X;
129 phdr.p_align = 0x1000;
130 memory_->SetMemory(0x100, &phdr, sizeof(phdr));
131 }
132
133 MemoryFake* memory_;
134};
135
136TEST_F(ElfTest, invalid_memory) {
137 Elf elf(memory_);
138
139 ASSERT_FALSE(elf.Init());
140 ASSERT_FALSE(elf.valid());
141}
142
143TEST_F(ElfTest, elf_invalid) {
144 Elf elf(memory_);
145
146 InitElf32(EM_386);
147
148 // Corrupt the ELF signature.
149 memory_->SetData32(0, 0x7f000000);
150
151 ASSERT_FALSE(elf.Init());
152 ASSERT_FALSE(elf.valid());
153 ASSERT_TRUE(elf.interface() == nullptr);
154
155 std::string name;
156 ASSERT_FALSE(elf.GetSoname(&name));
157
158 uint64_t func_offset;
159 ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset));
160
161 ASSERT_FALSE(elf.Step(0, nullptr, nullptr));
162}
163
164TEST_F(ElfTest, elf_arm) {
165 Elf elf(memory_);
166
167 InitElf32(EM_ARM);
168
169 ASSERT_TRUE(elf.Init());
170 ASSERT_TRUE(elf.valid());
171 ASSERT_EQ(static_cast<uint32_t>(EM_ARM), elf.machine_type());
172 ASSERT_EQ(ELFCLASS32, elf.class_type());
173 ASSERT_TRUE(elf.interface() != nullptr);
174}
175
176TEST_F(ElfTest, elf_x86) {
177 Elf elf(memory_);
178
179 InitElf32(EM_386);
180
181 ASSERT_TRUE(elf.Init());
182 ASSERT_TRUE(elf.valid());
183 ASSERT_EQ(static_cast<uint32_t>(EM_386), elf.machine_type());
184 ASSERT_EQ(ELFCLASS32, elf.class_type());
185 ASSERT_TRUE(elf.interface() != nullptr);
186}
187
188TEST_F(ElfTest, elf_arm64) {
189 Elf elf(memory_);
190
191 InitElf64(EM_AARCH64);
192
193 ASSERT_TRUE(elf.Init());
194 ASSERT_TRUE(elf.valid());
195 ASSERT_EQ(static_cast<uint32_t>(EM_AARCH64), elf.machine_type());
196 ASSERT_EQ(ELFCLASS64, elf.class_type());
197 ASSERT_TRUE(elf.interface() != nullptr);
198}
199
200TEST_F(ElfTest, elf_x86_64) {
201 Elf elf(memory_);
202
203 InitElf64(EM_X86_64);
204
205 ASSERT_TRUE(elf.Init());
206 ASSERT_TRUE(elf.valid());
207 ASSERT_EQ(static_cast<uint32_t>(EM_X86_64), elf.machine_type());
208 ASSERT_EQ(ELFCLASS64, elf.class_type());
209 ASSERT_TRUE(elf.interface() != nullptr);
210}