ElfTest.cpp revision 3958f8060ac0adccd977c0fab7a53d45f3fce58d
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
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}
211