ElfTest.cpp revision c3d79f7c0749a40d523b36807b8d7525cdb90654
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 <gmock/gmock.h> 24#include <gtest/gtest.h> 25 26#include <unwindstack/Elf.h> 27#include <unwindstack/MapInfo.h> 28 29#include "ElfFake.h" 30#include "ElfTestUtils.h" 31#include "LogFake.h" 32#include "MemoryFake.h" 33 34#if !defined(PT_ARM_EXIDX) 35#define PT_ARM_EXIDX 0x70000001 36#endif 37 38namespace unwindstack { 39 40class ElfTest : public ::testing::Test { 41 protected: 42 void SetUp() override { 43 memory_ = new MemoryFake; 44 } 45 46 void InitElf32(uint32_t machine_type) { 47 Elf32_Ehdr ehdr; 48 TestInitEhdr<Elf32_Ehdr>(&ehdr, ELFCLASS32, machine_type); 49 50 ehdr.e_phoff = 0x100; 51 ehdr.e_ehsize = sizeof(ehdr); 52 ehdr.e_phentsize = sizeof(Elf32_Phdr); 53 ehdr.e_phnum = 1; 54 ehdr.e_shentsize = sizeof(Elf32_Shdr); 55 if (machine_type == EM_ARM) { 56 ehdr.e_flags = 0x5000200; 57 ehdr.e_phnum = 2; 58 } 59 memory_->SetMemory(0, &ehdr, sizeof(ehdr)); 60 61 Elf32_Phdr phdr; 62 memset(&phdr, 0, sizeof(phdr)); 63 phdr.p_type = PT_LOAD; 64 phdr.p_filesz = 0x10000; 65 phdr.p_memsz = 0x10000; 66 phdr.p_flags = PF_R | PF_X; 67 phdr.p_align = 0x1000; 68 memory_->SetMemory(0x100, &phdr, sizeof(phdr)); 69 70 if (machine_type == EM_ARM) { 71 memset(&phdr, 0, sizeof(phdr)); 72 phdr.p_type = PT_ARM_EXIDX; 73 phdr.p_offset = 0x30000; 74 phdr.p_vaddr = 0x30000; 75 phdr.p_paddr = 0x30000; 76 phdr.p_filesz = 16; 77 phdr.p_memsz = 16; 78 phdr.p_flags = PF_R; 79 phdr.p_align = 0x4; 80 memory_->SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr)); 81 } 82 } 83 84 void InitElf64(uint32_t machine_type) { 85 Elf64_Ehdr ehdr; 86 TestInitEhdr<Elf64_Ehdr>(&ehdr, ELFCLASS64, machine_type); 87 88 ehdr.e_phoff = 0x100; 89 ehdr.e_flags = 0x5000200; 90 ehdr.e_ehsize = sizeof(ehdr); 91 ehdr.e_phentsize = sizeof(Elf64_Phdr); 92 ehdr.e_phnum = 1; 93 ehdr.e_shentsize = sizeof(Elf64_Shdr); 94 memory_->SetMemory(0, &ehdr, sizeof(ehdr)); 95 96 Elf64_Phdr phdr; 97 memset(&phdr, 0, sizeof(phdr)); 98 phdr.p_type = PT_LOAD; 99 phdr.p_filesz = 0x10000; 100 phdr.p_memsz = 0x10000; 101 phdr.p_flags = PF_R | PF_X; 102 phdr.p_align = 0x1000; 103 memory_->SetMemory(0x100, &phdr, sizeof(phdr)); 104 } 105 106 MemoryFake* memory_; 107}; 108 109TEST_F(ElfTest, invalid_memory) { 110 Elf elf(memory_); 111 112 ASSERT_FALSE(elf.Init(false)); 113 ASSERT_FALSE(elf.valid()); 114} 115 116TEST_F(ElfTest, elf_invalid) { 117 Elf elf(memory_); 118 119 InitElf32(EM_386); 120 121 // Corrupt the ELF signature. 122 memory_->SetData32(0, 0x7f000000); 123 124 ASSERT_FALSE(elf.Init(false)); 125 ASSERT_FALSE(elf.valid()); 126 ASSERT_TRUE(elf.interface() == nullptr); 127 128 std::string name; 129 ASSERT_FALSE(elf.GetSoname(&name)); 130 131 uint64_t func_offset; 132 ASSERT_FALSE(elf.GetFunctionName(0, &name, &func_offset)); 133 134 bool finished; 135 ASSERT_FALSE(elf.Step(0, 0, 0, nullptr, nullptr, &finished)); 136} 137 138TEST_F(ElfTest, elf32_invalid_machine) { 139 Elf elf(memory_); 140 141 InitElf32(EM_PPC); 142 143 ResetLogs(); 144 ASSERT_FALSE(elf.Init(false)); 145 146 ASSERT_EQ("", GetFakeLogBuf()); 147 ASSERT_EQ("4 unwind 32 bit elf that is neither arm nor x86: e_machine = 20\n\n", 148 GetFakeLogPrint()); 149} 150 151TEST_F(ElfTest, elf64_invalid_machine) { 152 Elf elf(memory_); 153 154 InitElf64(EM_PPC64); 155 156 ResetLogs(); 157 ASSERT_FALSE(elf.Init(false)); 158 159 ASSERT_EQ("", GetFakeLogBuf()); 160 ASSERT_EQ("4 unwind 64 bit elf that is neither aarch64 nor x86_64: e_machine = 21\n\n", 161 GetFakeLogPrint()); 162} 163 164TEST_F(ElfTest, elf_arm) { 165 Elf elf(memory_); 166 167 InitElf32(EM_ARM); 168 169 ASSERT_TRUE(elf.Init(false)); 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(false)); 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(false)); 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(false)); 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 212TEST_F(ElfTest, gnu_debugdata_init_fail32) { 213 TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, false, 214 [&](uint64_t offset, const void* ptr, size_t size) { 215 memory_->SetMemory(offset, ptr, size); 216 }); 217 218 Elf elf(memory_); 219 ASSERT_TRUE(elf.Init(false)); 220 ASSERT_TRUE(elf.interface() != nullptr); 221 ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr); 222 EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset()); 223 EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size()); 224} 225 226TEST_F(ElfTest, gnu_debugdata_init_fail64) { 227 TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, false, 228 [&](uint64_t offset, const void* ptr, size_t size) { 229 memory_->SetMemory(offset, ptr, size); 230 }); 231 232 Elf elf(memory_); 233 ASSERT_TRUE(elf.Init(false)); 234 ASSERT_TRUE(elf.interface() != nullptr); 235 ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr); 236 EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset()); 237 EXPECT_EQ(0x100U, elf.interface()->gnu_debugdata_size()); 238} 239 240TEST_F(ElfTest, gnu_debugdata_init32) { 241 TestInitGnuDebugdata<Elf32_Ehdr, Elf32_Shdr>(ELFCLASS32, EM_ARM, true, 242 [&](uint64_t offset, const void* ptr, size_t size) { 243 memory_->SetMemory(offset, ptr, size); 244 }); 245 246 Elf elf(memory_); 247 ASSERT_TRUE(elf.Init(true)); 248 ASSERT_TRUE(elf.interface() != nullptr); 249 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr); 250 EXPECT_EQ(0x1acU, elf.interface()->gnu_debugdata_offset()); 251 EXPECT_EQ(0x8cU, elf.interface()->gnu_debugdata_size()); 252} 253 254TEST_F(ElfTest, gnu_debugdata_init64) { 255 TestInitGnuDebugdata<Elf64_Ehdr, Elf64_Shdr>(ELFCLASS64, EM_AARCH64, true, 256 [&](uint64_t offset, const void* ptr, size_t size) { 257 memory_->SetMemory(offset, ptr, size); 258 }); 259 260 Elf elf(memory_); 261 ASSERT_TRUE(elf.Init(true)); 262 ASSERT_TRUE(elf.interface() != nullptr); 263 ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr); 264 EXPECT_EQ(0x200U, elf.interface()->gnu_debugdata_offset()); 265 EXPECT_EQ(0x90U, elf.interface()->gnu_debugdata_size()); 266} 267 268TEST_F(ElfTest, rel_pc) { 269 ElfFake elf(memory_); 270 271 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_); 272 elf.FakeSetInterface(interface); 273 274 elf.FakeSetValid(true); 275 elf.FakeSetLoadBias(0); 276 MapInfo map_info(0x1000, 0x2000); 277 278 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info)); 279 280 elf.FakeSetLoadBias(0x3000); 281 ASSERT_EQ(0x3101U, elf.GetRelPc(0x1101, &map_info)); 282 283 elf.FakeSetValid(false); 284 elf.FakeSetLoadBias(0); 285 ASSERT_EQ(0x101U, elf.GetRelPc(0x1101, &map_info)); 286} 287 288TEST_F(ElfTest, step_in_signal_map) { 289 ElfFake elf(memory_); 290 291 RegsArm regs; 292 regs[13] = 0x50000; 293 regs[15] = 0x8000; 294 regs.SetFromRaw(); 295 296 ElfInterfaceFake* interface = new ElfInterfaceFake(memory_); 297 elf.FakeSetInterface(interface); 298 299 memory_->SetData32(0x3000, 0xdf0027ad); 300 MemoryFake process_memory; 301 process_memory.SetData32(0x50000, 0); 302 for (size_t i = 0; i < 16; i++) { 303 process_memory.SetData32(0x500a0 + i * sizeof(uint32_t), i); 304 } 305 306 elf.FakeSetValid(true); 307 elf.FakeSetLoadBias(0); 308 bool finished; 309 ASSERT_TRUE(elf.Step(0x1000, 0x1000, 0x2000, ®s, &process_memory, &finished)); 310 EXPECT_FALSE(finished); 311 EXPECT_EQ(15U, regs.pc()); 312 EXPECT_EQ(13U, regs.sp()); 313} 314 315class ElfInterfaceMock : public ElfInterface { 316 public: 317 ElfInterfaceMock(Memory* memory) : ElfInterface(memory) {} 318 virtual ~ElfInterfaceMock() = default; 319 320 bool Init(uint64_t*) override { return false; } 321 void InitHeaders() override {} 322 bool GetSoname(std::string*) override { return false; } 323 bool GetFunctionName(uint64_t, uint64_t, std::string*, uint64_t*) override { return false; } 324 MOCK_METHOD4(Step, bool(uint64_t, Regs*, Memory*, bool*)); 325}; 326 327TEST_F(ElfTest, step_in_interface) { 328 ElfFake elf(memory_); 329 elf.FakeSetValid(true); 330 elf.FakeSetLoadBias(0); 331 332 RegsArm regs; 333 334 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_); 335 elf.FakeSetInterface(interface); 336 MemoryFake process_memory; 337 338 bool finished; 339 EXPECT_CALL(*interface, Step(0x1000, ®s, &process_memory, &finished)) 340 .WillOnce(::testing::Return(true)); 341 342 ASSERT_TRUE(elf.Step(0x1004, 0x1000, 0x2000, ®s, &process_memory, &finished)); 343} 344 345TEST_F(ElfTest, step_in_interface_non_zero_load_bias) { 346 ElfFake elf(memory_); 347 elf.FakeSetValid(true); 348 elf.FakeSetLoadBias(0x4000); 349 350 RegsArm regs; 351 352 ElfInterfaceMock* interface = new ElfInterfaceMock(memory_); 353 elf.FakeSetInterface(interface); 354 MemoryFake process_memory; 355 356 // Invalid relative pc given load_bias. 357 bool finished; 358 ASSERT_FALSE(elf.Step(0x1004, 0x1000, 0x2000, ®s, &process_memory, &finished)); 359 360 EXPECT_CALL(*interface, Step(0x3300, ®s, &process_memory, &finished)) 361 .WillOnce(::testing::Return(true)); 362 363 ASSERT_TRUE(elf.Step(0x7304, 0x7300, 0x2000, ®s, &process_memory, &finished)); 364} 365 366} // namespace unwindstack 367