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