1 /* 2 * Copyright (C) 2018 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 <string.h> 19 20 #include <memory> 21 #include <vector> 22 23 #include <gtest/gtest.h> 24 25 #include <unwindstack/Elf.h> 26 #include <unwindstack/JitDebug.h> 27 #include <unwindstack/MapInfo.h> 28 #include <unwindstack/Maps.h> 29 #include <unwindstack/Memory.h> 30 31 #include "ElfFake.h" 32 #include "MemoryFake.h" 33 34 namespace unwindstack { 35 36 class JitDebugTest : public ::testing::Test { 37 protected: 38 void SetUp() override { 39 memory_ = new MemoryFake; 40 process_memory_.reset(memory_); 41 42 jit_debug_.reset(new JitDebug(process_memory_)); 43 jit_debug_->SetArch(ARCH_ARM); 44 45 maps_.reset( 46 new BufferMaps("1000-4000 ---s 00000000 00:00 0\n" 47 "4000-6000 r--s 00000000 00:00 0\n" 48 "6000-8000 -w-s 00000000 00:00 0\n" 49 "a000-c000 --xp 00000000 00:00 0\n" 50 "c000-f000 rwxp 00000000 00:00 0\n" 51 "f000-11000 r-xp 00000000 00:00 0\n" 52 "12000-14000 r-xp 00000000 00:00 0\n" 53 "100000-110000 rw-p 0000000 00:00 0\n" 54 "200000-210000 rw-p 0000000 00:00 0\n")); 55 ASSERT_TRUE(maps_->Parse()); 56 57 MapInfo* map_info = maps_->Get(3); 58 ASSERT_TRUE(map_info != nullptr); 59 MemoryFake* memory = new MemoryFake; 60 ElfFake* elf = new ElfFake(memory); 61 elf->FakeSetValid(true); 62 ElfInterfaceFake* interface = new ElfInterfaceFake(memory); 63 elf->FakeSetInterface(interface); 64 interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800); 65 map_info->elf.reset(elf); 66 67 map_info = maps_->Get(5); 68 ASSERT_TRUE(map_info != nullptr); 69 memory = new MemoryFake; 70 elf = new ElfFake(memory); 71 elf->FakeSetValid(true); 72 interface = new ElfInterfaceFake(memory); 73 elf->FakeSetInterface(interface); 74 interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800); 75 map_info->elf.reset(elf); 76 77 map_info = maps_->Get(6); 78 ASSERT_TRUE(map_info != nullptr); 79 memory = new MemoryFake; 80 elf = new ElfFake(memory); 81 elf->FakeSetValid(true); 82 interface = new ElfInterfaceFake(memory); 83 elf->FakeSetInterface(interface); 84 interface->FakeSetGlobalVariable("__jit_debug_descriptor", 0x800); 85 map_info->elf.reset(elf); 86 } 87 88 template <typename EhdrType, typename ShdrType> 89 void CreateElf(uint64_t offset, uint8_t class_type, uint8_t machine_type, uint32_t pc, 90 uint32_t size) { 91 EhdrType ehdr; 92 memset(&ehdr, 0, sizeof(ehdr)); 93 uint64_t sh_offset = sizeof(ehdr); 94 memcpy(ehdr.e_ident, ELFMAG, SELFMAG); 95 ehdr.e_ident[EI_CLASS] = class_type; 96 ehdr.e_machine = machine_type; 97 ehdr.e_shstrndx = 1; 98 ehdr.e_shoff = sh_offset; 99 ehdr.e_shentsize = sizeof(ShdrType); 100 ehdr.e_shnum = 3; 101 memory_->SetMemory(offset, &ehdr, sizeof(ehdr)); 102 103 ShdrType shdr; 104 memset(&shdr, 0, sizeof(shdr)); 105 shdr.sh_type = SHT_NULL; 106 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); 107 108 sh_offset += sizeof(shdr); 109 memset(&shdr, 0, sizeof(shdr)); 110 shdr.sh_type = SHT_STRTAB; 111 shdr.sh_name = 1; 112 shdr.sh_offset = 0x500; 113 shdr.sh_size = 0x100; 114 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); 115 memory_->SetMemory(offset + 0x500, ".debug_frame"); 116 117 sh_offset += sizeof(shdr); 118 memset(&shdr, 0, sizeof(shdr)); 119 shdr.sh_type = SHT_PROGBITS; 120 shdr.sh_name = 0; 121 shdr.sh_addr = 0x600; 122 shdr.sh_offset = 0x600; 123 shdr.sh_size = 0x200; 124 memory_->SetMemory(offset + sh_offset, &shdr, sizeof(shdr)); 125 126 // Now add a single cie/fde. 127 uint64_t dwarf_offset = offset + 0x600; 128 if (class_type == ELFCLASS32) { 129 // CIE 32 information. 130 memory_->SetData32(dwarf_offset, 0xfc); 131 memory_->SetData32(dwarf_offset + 0x4, 0xffffffff); 132 memory_->SetData8(dwarf_offset + 0x8, 1); 133 memory_->SetData8(dwarf_offset + 0x9, '\0'); 134 memory_->SetData8(dwarf_offset + 0xa, 0x4); 135 memory_->SetData8(dwarf_offset + 0xb, 0x4); 136 memory_->SetData8(dwarf_offset + 0xc, 0x1); 137 138 // FDE 32 information. 139 memory_->SetData32(dwarf_offset + 0x100, 0xfc); 140 memory_->SetData32(dwarf_offset + 0x104, 0); 141 memory_->SetData32(dwarf_offset + 0x108, pc); 142 memory_->SetData32(dwarf_offset + 0x10c, size); 143 } else { 144 // CIE 64 information. 145 memory_->SetData32(dwarf_offset, 0xffffffff); 146 memory_->SetData64(dwarf_offset + 4, 0xf4); 147 memory_->SetData64(dwarf_offset + 0xc, 0xffffffffffffffffULL); 148 memory_->SetData8(dwarf_offset + 0x14, 1); 149 memory_->SetData8(dwarf_offset + 0x15, '\0'); 150 memory_->SetData8(dwarf_offset + 0x16, 0x4); 151 memory_->SetData8(dwarf_offset + 0x17, 0x4); 152 memory_->SetData8(dwarf_offset + 0x18, 0x1); 153 154 // FDE 64 information. 155 memory_->SetData32(dwarf_offset + 0x100, 0xffffffff); 156 memory_->SetData64(dwarf_offset + 0x104, 0xf4); 157 memory_->SetData64(dwarf_offset + 0x10c, 0); 158 memory_->SetData64(dwarf_offset + 0x114, pc); 159 memory_->SetData64(dwarf_offset + 0x11c, size); 160 } 161 } 162 163 void WriteDescriptor32(uint64_t addr, uint32_t entry); 164 void WriteDescriptor64(uint64_t addr, uint64_t entry); 165 void WriteEntry32Pack(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr, 166 uint64_t elf_size); 167 void WriteEntry32Pad(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr, 168 uint64_t elf_size); 169 void WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uint64_t elf_addr, 170 uint64_t elf_size); 171 172 std::shared_ptr<Memory> process_memory_; 173 MemoryFake* memory_; 174 std::unique_ptr<JitDebug> jit_debug_; 175 std::unique_ptr<BufferMaps> maps_; 176 }; 177 178 void JitDebugTest::WriteDescriptor32(uint64_t addr, uint32_t entry) { 179 // Format of the 32 bit JITDescriptor structure: 180 // uint32_t version 181 memory_->SetData32(addr, 1); 182 // uint32_t action_flag 183 memory_->SetData32(addr + 4, 0); 184 // uint32_t relevant_entry 185 memory_->SetData32(addr + 8, 0); 186 // uint32_t first_entry 187 memory_->SetData32(addr + 12, entry); 188 } 189 190 void JitDebugTest::WriteDescriptor64(uint64_t addr, uint64_t entry) { 191 // Format of the 64 bit JITDescriptor structure: 192 // uint32_t version 193 memory_->SetData32(addr, 1); 194 // uint32_t action_flag 195 memory_->SetData32(addr + 4, 0); 196 // uint64_t relevant_entry 197 memory_->SetData64(addr + 8, 0); 198 // uint64_t first_entry 199 memory_->SetData64(addr + 16, entry); 200 } 201 202 void JitDebugTest::WriteEntry32Pack(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr, 203 uint64_t elf_size) { 204 // Format of the 32 bit JITCodeEntry structure: 205 // uint32_t next 206 memory_->SetData32(addr, next); 207 // uint32_t prev 208 memory_->SetData32(addr + 4, prev); 209 // uint32_t symfile_addr 210 memory_->SetData32(addr + 8, elf_addr); 211 // uint64_t symfile_size 212 memory_->SetData64(addr + 12, elf_size); 213 } 214 215 void JitDebugTest::WriteEntry32Pad(uint64_t addr, uint32_t prev, uint32_t next, uint32_t elf_addr, 216 uint64_t elf_size) { 217 // Format of the 32 bit JITCodeEntry structure: 218 // uint32_t next 219 memory_->SetData32(addr, next); 220 // uint32_t prev 221 memory_->SetData32(addr + 4, prev); 222 // uint32_t symfile_addr 223 memory_->SetData32(addr + 8, elf_addr); 224 // uint32_t pad 225 memory_->SetData32(addr + 12, 0); 226 // uint64_t symfile_size 227 memory_->SetData64(addr + 16, elf_size); 228 } 229 230 void JitDebugTest::WriteEntry64(uint64_t addr, uint64_t prev, uint64_t next, uint64_t elf_addr, 231 uint64_t elf_size) { 232 // Format of the 64 bit JITCodeEntry structure: 233 // uint64_t next 234 memory_->SetData64(addr, next); 235 // uint64_t prev 236 memory_->SetData64(addr + 8, prev); 237 // uint64_t symfile_addr 238 memory_->SetData64(addr + 16, elf_addr); 239 // uint64_t symfile_size 240 memory_->SetData64(addr + 24, elf_size); 241 } 242 243 TEST_F(JitDebugTest, get_elf_invalid) { 244 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 245 ASSERT_TRUE(elf == nullptr); 246 } 247 248 TEST_F(JitDebugTest, get_elf_no_global_variable) { 249 maps_.reset(new BufferMaps("")); 250 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 251 ASSERT_TRUE(elf == nullptr); 252 } 253 254 TEST_F(JitDebugTest, get_elf_no_valid_descriptor_in_memory) { 255 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 256 257 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 258 ASSERT_TRUE(elf == nullptr); 259 } 260 261 TEST_F(JitDebugTest, get_elf_no_valid_code_entry) { 262 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 263 264 WriteDescriptor32(0xf800, 0x200000); 265 266 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 267 ASSERT_TRUE(elf == nullptr); 268 } 269 270 TEST_F(JitDebugTest, get_elf_invalid_descriptor_first_entry) { 271 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 272 273 WriteDescriptor32(0xf800, 0); 274 275 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 276 ASSERT_TRUE(elf == nullptr); 277 } 278 279 TEST_F(JitDebugTest, get_elf_invalid_descriptor_version) { 280 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 281 282 WriteDescriptor32(0xf800, 0x20000); 283 // Set the version to an invalid value. 284 memory_->SetData32(0xf800, 2); 285 286 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 287 ASSERT_TRUE(elf == nullptr); 288 } 289 290 TEST_F(JitDebugTest, get_elf_32) { 291 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 292 293 WriteDescriptor32(0xf800, 0x200000); 294 WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000); 295 296 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 297 ASSERT_TRUE(elf != nullptr); 298 299 // Clear the memory and verify all of the data is cached. 300 memory_->Clear(); 301 Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); 302 ASSERT_TRUE(elf2 != nullptr); 303 EXPECT_EQ(elf, elf2); 304 } 305 306 TEST_F(JitDebugTest, get_multiple_jit_debug_descriptors_valid) { 307 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 308 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x5000, ELFCLASS32, EM_ARM, 0x2000, 0x300); 309 310 WriteDescriptor32(0xf800, 0x200000); 311 WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000); 312 WriteDescriptor32(0x12800, 0x201000); 313 WriteEntry32Pad(0x201000, 0, 0, 0x5000, 0x1000); 314 315 ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr); 316 ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) == nullptr); 317 318 // Now clear the descriptor entry for the first one. 319 WriteDescriptor32(0xf800, 0); 320 jit_debug_.reset(new JitDebug(process_memory_)); 321 jit_debug_->SetArch(ARCH_ARM); 322 323 ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr); 324 ASSERT_TRUE(jit_debug_->GetElf(maps_.get(), 0x2000) != nullptr); 325 } 326 327 TEST_F(JitDebugTest, get_elf_x86) { 328 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 329 330 WriteDescriptor32(0xf800, 0x200000); 331 WriteEntry32Pack(0x200000, 0, 0, 0x4000, 0x1000); 332 333 jit_debug_->SetArch(ARCH_X86); 334 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 335 ASSERT_TRUE(elf != nullptr); 336 337 // Clear the memory and verify all of the data is cached. 338 memory_->Clear(); 339 Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); 340 ASSERT_TRUE(elf2 != nullptr); 341 EXPECT_EQ(elf, elf2); 342 } 343 344 TEST_F(JitDebugTest, get_elf_64) { 345 CreateElf<Elf64_Ehdr, Elf64_Shdr>(0x4000, ELFCLASS64, EM_AARCH64, 0x1500, 0x200); 346 347 WriteDescriptor64(0xf800, 0x200000); 348 WriteEntry64(0x200000, 0, 0, 0x4000, 0x1000); 349 350 jit_debug_->SetArch(ARCH_ARM64); 351 Elf* elf = jit_debug_->GetElf(maps_.get(), 0x1500); 352 ASSERT_TRUE(elf != nullptr); 353 354 // Clear the memory and verify all of the data is cached. 355 memory_->Clear(); 356 Elf* elf2 = jit_debug_->GetElf(maps_.get(), 0x1500); 357 ASSERT_TRUE(elf2 != nullptr); 358 EXPECT_EQ(elf, elf2); 359 } 360 361 TEST_F(JitDebugTest, get_elf_multiple_entries) { 362 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 363 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x5000, ELFCLASS32, EM_ARM, 0x2300, 0x400); 364 365 WriteDescriptor32(0xf800, 0x200000); 366 WriteEntry32Pad(0x200000, 0, 0x200100, 0x4000, 0x1000); 367 WriteEntry32Pad(0x200100, 0x200100, 0, 0x5000, 0x1000); 368 369 Elf* elf_2 = jit_debug_->GetElf(maps_.get(), 0x2400); 370 ASSERT_TRUE(elf_2 != nullptr); 371 372 Elf* elf_1 = jit_debug_->GetElf(maps_.get(), 0x1600); 373 ASSERT_TRUE(elf_1 != nullptr); 374 375 // Clear the memory and verify all of the data is cached. 376 memory_->Clear(); 377 EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x1500)); 378 EXPECT_EQ(elf_1, jit_debug_->GetElf(maps_.get(), 0x16ff)); 379 EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x2300)); 380 EXPECT_EQ(elf_2, jit_debug_->GetElf(maps_.get(), 0x26ff)); 381 EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x1700)); 382 EXPECT_EQ(nullptr, jit_debug_->GetElf(maps_.get(), 0x2700)); 383 } 384 385 TEST_F(JitDebugTest, get_elf_search_libs) { 386 CreateElf<Elf32_Ehdr, Elf32_Shdr>(0x4000, ELFCLASS32, EM_ARM, 0x1500, 0x200); 387 388 WriteDescriptor32(0xf800, 0x200000); 389 WriteEntry32Pad(0x200000, 0, 0, 0x4000, 0x1000); 390 391 // Only search a given named list of libs. 392 std::vector<std::string> libs{"libart.so"}; 393 jit_debug_.reset(new JitDebug(process_memory_, libs)); 394 jit_debug_->SetArch(ARCH_ARM); 395 EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) == nullptr); 396 397 // Change the name of the map that includes the value and verify this works. 398 MapInfo* map_info = maps_->Get(5); 399 map_info->name = "/system/lib/libart.so"; 400 jit_debug_.reset(new JitDebug(process_memory_, libs)); 401 // Make sure that clearing our copy of the libs doesn't affect the 402 // JitDebug object. 403 libs.clear(); 404 jit_debug_->SetArch(ARCH_ARM); 405 EXPECT_TRUE(jit_debug_->GetElf(maps_.get(), 0x1500) != nullptr); 406 } 407 408 } // namespace unwindstack 409