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