1 /* 2 * Copyright (C) 2012 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_file.h" 18 19 #include <inttypes.h> 20 #include <sys/types.h> 21 #include <unistd.h> 22 23 #include "arch/instruction_set.h" 24 #include "base/logging.h" 25 #include "base/stringprintf.h" 26 #include "base/stl_util.h" 27 #include "base/unix_file/fd_file.h" 28 #include "elf_file_impl.h" 29 #include "elf_utils.h" 30 #include "leb128.h" 31 #include "utils.h" 32 33 namespace art { 34 35 // ------------------------------------------------------------------- 36 // Binary GDB JIT Interface as described in 37 // http://sourceware.org/gdb/onlinedocs/gdb/Declarations.html 38 extern "C" { 39 typedef enum { 40 JIT_NOACTION = 0, 41 JIT_REGISTER_FN, 42 JIT_UNREGISTER_FN 43 } JITAction; 44 45 struct JITCodeEntry { 46 JITCodeEntry* next_; 47 JITCodeEntry* prev_; 48 const uint8_t *symfile_addr_; 49 uint64_t symfile_size_; 50 }; 51 52 struct JITDescriptor { 53 uint32_t version_; 54 uint32_t action_flag_; 55 JITCodeEntry* relevant_entry_; 56 JITCodeEntry* first_entry_; 57 }; 58 59 // GDB will place breakpoint into this function. 60 // To prevent GCC from inlining or removing it we place noinline attribute 61 // and inline assembler statement inside. 62 void __attribute__((noinline)) __jit_debug_register_code(); 63 void __attribute__((noinline)) __jit_debug_register_code() { 64 __asm__(""); 65 } 66 67 // GDB will inspect contents of this descriptor. 68 // Static initialization is necessary to prevent GDB from seeing 69 // uninitialized descriptor. 70 JITDescriptor __jit_debug_descriptor = { 1, JIT_NOACTION, nullptr, nullptr }; 71 } 72 73 74 static JITCodeEntry* CreateCodeEntry(const uint8_t *symfile_addr, 75 uintptr_t symfile_size) { 76 JITCodeEntry* entry = new JITCodeEntry; 77 entry->symfile_addr_ = symfile_addr; 78 entry->symfile_size_ = symfile_size; 79 entry->prev_ = nullptr; 80 81 // TODO: Do we need a lock here? 82 entry->next_ = __jit_debug_descriptor.first_entry_; 83 if (entry->next_ != nullptr) { 84 entry->next_->prev_ = entry; 85 } 86 __jit_debug_descriptor.first_entry_ = entry; 87 __jit_debug_descriptor.relevant_entry_ = entry; 88 89 __jit_debug_descriptor.action_flag_ = JIT_REGISTER_FN; 90 __jit_debug_register_code(); 91 return entry; 92 } 93 94 95 static void UnregisterCodeEntry(JITCodeEntry* entry) { 96 // TODO: Do we need a lock here? 97 if (entry->prev_ != nullptr) { 98 entry->prev_->next_ = entry->next_; 99 } else { 100 __jit_debug_descriptor.first_entry_ = entry->next_; 101 } 102 103 if (entry->next_ != nullptr) { 104 entry->next_->prev_ = entry->prev_; 105 } 106 107 __jit_debug_descriptor.relevant_entry_ = entry; 108 __jit_debug_descriptor.action_flag_ = JIT_UNREGISTER_FN; 109 __jit_debug_register_code(); 110 delete entry; 111 } 112 113 template <typename ElfTypes> 114 ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable, 115 bool program_header_only, 116 uint8_t* requested_base) 117 : file_(file), 118 writable_(writable), 119 program_header_only_(program_header_only), 120 header_(nullptr), 121 base_address_(nullptr), 122 program_headers_start_(nullptr), 123 section_headers_start_(nullptr), 124 dynamic_program_header_(nullptr), 125 dynamic_section_start_(nullptr), 126 symtab_section_start_(nullptr), 127 dynsym_section_start_(nullptr), 128 strtab_section_start_(nullptr), 129 dynstr_section_start_(nullptr), 130 hash_section_start_(nullptr), 131 symtab_symbol_table_(nullptr), 132 dynsym_symbol_table_(nullptr), 133 jit_elf_image_(nullptr), 134 jit_gdb_entry_(nullptr), 135 requested_base_(requested_base) { 136 CHECK(file != nullptr); 137 } 138 139 template <typename ElfTypes> 140 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open( 141 File* file, bool writable, bool program_header_only, 142 std::string* error_msg, uint8_t* requested_base) { 143 std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes> 144 (file, writable, program_header_only, requested_base)); 145 int prot; 146 int flags; 147 if (writable) { 148 prot = PROT_READ | PROT_WRITE; 149 flags = MAP_SHARED; 150 } else { 151 prot = PROT_READ; 152 flags = MAP_PRIVATE; 153 } 154 if (!elf_file->Setup(prot, flags, error_msg)) { 155 return nullptr; 156 } 157 return elf_file.release(); 158 } 159 160 template <typename ElfTypes> 161 ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open( 162 File* file, int prot, int flags, std::string* error_msg) { 163 std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes> 164 (file, (prot & PROT_WRITE) == PROT_WRITE, /*program_header_only*/false, 165 /*requested_base*/nullptr)); 166 if (!elf_file->Setup(prot, flags, error_msg)) { 167 return nullptr; 168 } 169 return elf_file.release(); 170 } 171 172 template <typename ElfTypes> 173 bool ElfFileImpl<ElfTypes>::Setup(int prot, int flags, std::string* error_msg) { 174 int64_t temp_file_length = file_->GetLength(); 175 if (temp_file_length < 0) { 176 errno = -temp_file_length; 177 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s", 178 file_->GetPath().c_str(), file_->Fd(), strerror(errno)); 179 return false; 180 } 181 size_t file_length = static_cast<size_t>(temp_file_length); 182 if (file_length < sizeof(Elf_Ehdr)) { 183 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF header of " 184 "%zd bytes: '%s'", file_length, sizeof(Elf_Ehdr), 185 file_->GetPath().c_str()); 186 return false; 187 } 188 189 if (program_header_only_) { 190 // first just map ELF header to get program header size information 191 size_t elf_header_size = sizeof(Elf_Ehdr); 192 if (!SetMap(MemMap::MapFile(elf_header_size, prot, flags, file_->Fd(), 0, 193 file_->GetPath().c_str(), error_msg), 194 error_msg)) { 195 return false; 196 } 197 // then remap to cover program header 198 size_t program_header_size = header_->e_phoff + (header_->e_phentsize * header_->e_phnum); 199 if (file_length < program_header_size) { 200 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF program " 201 "header of %zd bytes: '%s'", file_length, 202 sizeof(Elf_Ehdr), file_->GetPath().c_str()); 203 return false; 204 } 205 if (!SetMap(MemMap::MapFile(program_header_size, prot, flags, file_->Fd(), 0, 206 file_->GetPath().c_str(), error_msg), 207 error_msg)) { 208 *error_msg = StringPrintf("Failed to map ELF program headers: %s", error_msg->c_str()); 209 return false; 210 } 211 } else { 212 // otherwise map entire file 213 if (!SetMap(MemMap::MapFile(file_->GetLength(), prot, flags, file_->Fd(), 0, 214 file_->GetPath().c_str(), error_msg), 215 error_msg)) { 216 *error_msg = StringPrintf("Failed to map ELF file: %s", error_msg->c_str()); 217 return false; 218 } 219 } 220 221 if (program_header_only_) { 222 program_headers_start_ = Begin() + GetHeader().e_phoff; 223 } else { 224 if (!CheckAndSet(GetHeader().e_phoff, "program headers", &program_headers_start_, error_msg)) { 225 return false; 226 } 227 228 // Setup section headers. 229 if (!CheckAndSet(GetHeader().e_shoff, "section headers", §ion_headers_start_, error_msg)) { 230 return false; 231 } 232 233 // Find shstrtab. 234 Elf_Shdr* shstrtab_section_header = GetSectionNameStringSection(); 235 if (shstrtab_section_header == nullptr) { 236 *error_msg = StringPrintf("Failed to find shstrtab section header in ELF file: '%s'", 237 file_->GetPath().c_str()); 238 return false; 239 } 240 241 // Find .dynamic section info from program header 242 dynamic_program_header_ = FindProgamHeaderByType(PT_DYNAMIC); 243 if (dynamic_program_header_ == nullptr) { 244 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'", 245 file_->GetPath().c_str()); 246 return false; 247 } 248 249 if (!CheckAndSet(GetDynamicProgramHeader().p_offset, "dynamic section", 250 reinterpret_cast<uint8_t**>(&dynamic_section_start_), error_msg)) { 251 return false; 252 } 253 254 // Find other sections from section headers 255 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 256 Elf_Shdr* section_header = GetSectionHeader(i); 257 if (section_header == nullptr) { 258 *error_msg = StringPrintf("Failed to find section header for section %d in ELF file: '%s'", 259 i, file_->GetPath().c_str()); 260 return false; 261 } 262 switch (section_header->sh_type) { 263 case SHT_SYMTAB: { 264 if (!CheckAndSet(section_header->sh_offset, "symtab", 265 reinterpret_cast<uint8_t**>(&symtab_section_start_), error_msg)) { 266 return false; 267 } 268 break; 269 } 270 case SHT_DYNSYM: { 271 if (!CheckAndSet(section_header->sh_offset, "dynsym", 272 reinterpret_cast<uint8_t**>(&dynsym_section_start_), error_msg)) { 273 return false; 274 } 275 break; 276 } 277 case SHT_STRTAB: { 278 // TODO: base these off of sh_link from .symtab and .dynsym above 279 if ((section_header->sh_flags & SHF_ALLOC) != 0) { 280 // Check that this is named ".dynstr" and ignore otherwise. 281 const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name); 282 if (strncmp(".dynstr", header_name, 8) == 0) { 283 if (!CheckAndSet(section_header->sh_offset, "dynstr", 284 reinterpret_cast<uint8_t**>(&dynstr_section_start_), error_msg)) { 285 return false; 286 } 287 } 288 } else { 289 // Check that this is named ".strtab" and ignore otherwise. 290 const char* header_name = GetString(*shstrtab_section_header, section_header->sh_name); 291 if (strncmp(".strtab", header_name, 8) == 0) { 292 if (!CheckAndSet(section_header->sh_offset, "strtab", 293 reinterpret_cast<uint8_t**>(&strtab_section_start_), error_msg)) { 294 return false; 295 } 296 } 297 } 298 break; 299 } 300 case SHT_DYNAMIC: { 301 if (reinterpret_cast<uint8_t*>(dynamic_section_start_) != 302 Begin() + section_header->sh_offset) { 303 LOG(WARNING) << "Failed to find matching SHT_DYNAMIC for PT_DYNAMIC in " 304 << file_->GetPath() << ": " << std::hex 305 << reinterpret_cast<void*>(dynamic_section_start_) 306 << " != " << reinterpret_cast<void*>(Begin() + section_header->sh_offset); 307 return false; 308 } 309 break; 310 } 311 case SHT_HASH: { 312 if (!CheckAndSet(section_header->sh_offset, "hash section", 313 reinterpret_cast<uint8_t**>(&hash_section_start_), error_msg)) { 314 return false; 315 } 316 break; 317 } 318 } 319 } 320 321 // Check for the existence of some sections. 322 if (!CheckSectionsExist(error_msg)) { 323 return false; 324 } 325 } 326 327 return true; 328 } 329 330 template <typename ElfTypes> 331 ElfFileImpl<ElfTypes>::~ElfFileImpl() { 332 STLDeleteElements(&segments_); 333 delete symtab_symbol_table_; 334 delete dynsym_symbol_table_; 335 delete jit_elf_image_; 336 if (jit_gdb_entry_) { 337 UnregisterCodeEntry(jit_gdb_entry_); 338 } 339 } 340 341 template <typename ElfTypes> 342 bool ElfFileImpl<ElfTypes>::CheckAndSet(Elf32_Off offset, const char* label, 343 uint8_t** target, std::string* error_msg) { 344 if (Begin() + offset >= End()) { 345 *error_msg = StringPrintf("Offset %d is out of range for %s in ELF file: '%s'", offset, label, 346 file_->GetPath().c_str()); 347 return false; 348 } 349 *target = Begin() + offset; 350 return true; 351 } 352 353 template <typename ElfTypes> 354 bool ElfFileImpl<ElfTypes>::CheckSectionsLinked(const uint8_t* source, 355 const uint8_t* target) const { 356 // Only works in whole-program mode, as we need to iterate over the sections. 357 // Note that we normally can't search by type, as duplicates are allowed for most section types. 358 if (program_header_only_) { 359 return true; 360 } 361 362 Elf_Shdr* source_section = nullptr; 363 Elf_Word target_index = 0; 364 bool target_found = false; 365 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 366 Elf_Shdr* section_header = GetSectionHeader(i); 367 368 if (Begin() + section_header->sh_offset == source) { 369 // Found the source. 370 source_section = section_header; 371 if (target_index) { 372 break; 373 } 374 } else if (Begin() + section_header->sh_offset == target) { 375 target_index = i; 376 target_found = true; 377 if (source_section != nullptr) { 378 break; 379 } 380 } 381 } 382 383 return target_found && source_section != nullptr && source_section->sh_link == target_index; 384 } 385 386 template <typename ElfTypes> 387 bool ElfFileImpl<ElfTypes>::CheckSectionsExist(std::string* error_msg) const { 388 if (!program_header_only_) { 389 // If in full mode, need section headers. 390 if (section_headers_start_ == nullptr) { 391 *error_msg = StringPrintf("No section headers in ELF file: '%s'", file_->GetPath().c_str()); 392 return false; 393 } 394 } 395 396 // This is redundant, but defensive. 397 if (dynamic_program_header_ == nullptr) { 398 *error_msg = StringPrintf("Failed to find PT_DYNAMIC program header in ELF file: '%s'", 399 file_->GetPath().c_str()); 400 return false; 401 } 402 403 // Need a dynamic section. This is redundant, but defensive. 404 if (dynamic_section_start_ == nullptr) { 405 *error_msg = StringPrintf("Failed to find dynamic section in ELF file: '%s'", 406 file_->GetPath().c_str()); 407 return false; 408 } 409 410 // Symtab validation. These is not really a hard failure, as we are currently not using the 411 // symtab internally, but it's nice to be defensive. 412 if (symtab_section_start_ != nullptr) { 413 // When there's a symtab, there should be a strtab. 414 if (strtab_section_start_ == nullptr) { 415 *error_msg = StringPrintf("No strtab for symtab in ELF file: '%s'", file_->GetPath().c_str()); 416 return false; 417 } 418 419 // The symtab should link to the strtab. 420 if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(symtab_section_start_), 421 reinterpret_cast<const uint8_t*>(strtab_section_start_))) { 422 *error_msg = StringPrintf("Symtab is not linked to the strtab in ELF file: '%s'", 423 file_->GetPath().c_str()); 424 return false; 425 } 426 } 427 428 // We always need a dynstr & dynsym. 429 if (dynstr_section_start_ == nullptr) { 430 *error_msg = StringPrintf("No dynstr in ELF file: '%s'", file_->GetPath().c_str()); 431 return false; 432 } 433 if (dynsym_section_start_ == nullptr) { 434 *error_msg = StringPrintf("No dynsym in ELF file: '%s'", file_->GetPath().c_str()); 435 return false; 436 } 437 438 // Need a hash section for dynamic symbol lookup. 439 if (hash_section_start_ == nullptr) { 440 *error_msg = StringPrintf("Failed to find hash section in ELF file: '%s'", 441 file_->GetPath().c_str()); 442 return false; 443 } 444 445 // And the hash section should be linking to the dynsym. 446 if (!CheckSectionsLinked(reinterpret_cast<const uint8_t*>(hash_section_start_), 447 reinterpret_cast<const uint8_t*>(dynsym_section_start_))) { 448 *error_msg = StringPrintf("Hash section is not linked to the dynstr in ELF file: '%s'", 449 file_->GetPath().c_str()); 450 return false; 451 } 452 453 // We'd also like to confirm a shstrtab in program_header_only_ mode (else Open() does this for 454 // us). This is usually the last in an oat file, and a good indicator of whether writing was 455 // successful (or the process crashed and left garbage). 456 if (program_header_only_) { 457 // It might not be mapped, but we can compare against the file size. 458 int64_t offset = static_cast<int64_t>(GetHeader().e_shoff + 459 (GetHeader().e_shstrndx * GetHeader().e_shentsize)); 460 if (offset >= file_->GetLength()) { 461 *error_msg = StringPrintf("Shstrtab is not in the mapped ELF file: '%s'", 462 file_->GetPath().c_str()); 463 return false; 464 } 465 } 466 467 return true; 468 } 469 470 template <typename ElfTypes> 471 bool ElfFileImpl<ElfTypes>::SetMap(MemMap* map, std::string* error_msg) { 472 if (map == nullptr) { 473 // MemMap::Open should have already set an error. 474 DCHECK(!error_msg->empty()); 475 return false; 476 } 477 map_.reset(map); 478 CHECK(map_.get() != nullptr) << file_->GetPath(); 479 CHECK(map_->Begin() != nullptr) << file_->GetPath(); 480 481 header_ = reinterpret_cast<Elf_Ehdr*>(map_->Begin()); 482 if ((ELFMAG0 != header_->e_ident[EI_MAG0]) 483 || (ELFMAG1 != header_->e_ident[EI_MAG1]) 484 || (ELFMAG2 != header_->e_ident[EI_MAG2]) 485 || (ELFMAG3 != header_->e_ident[EI_MAG3])) { 486 *error_msg = StringPrintf("Failed to find ELF magic value %d %d %d %d in %s, found %d %d %d %d", 487 ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, 488 file_->GetPath().c_str(), 489 header_->e_ident[EI_MAG0], 490 header_->e_ident[EI_MAG1], 491 header_->e_ident[EI_MAG2], 492 header_->e_ident[EI_MAG3]); 493 return false; 494 } 495 uint8_t elf_class = (sizeof(Elf_Addr) == sizeof(Elf64_Addr)) ? ELFCLASS64 : ELFCLASS32; 496 if (elf_class != header_->e_ident[EI_CLASS]) { 497 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d in %s, found %d", 498 elf_class, 499 file_->GetPath().c_str(), 500 header_->e_ident[EI_CLASS]); 501 return false; 502 } 503 if (ELFDATA2LSB != header_->e_ident[EI_DATA]) { 504 *error_msg = StringPrintf("Failed to find expected EI_DATA value %d in %s, found %d", 505 ELFDATA2LSB, 506 file_->GetPath().c_str(), 507 header_->e_ident[EI_CLASS]); 508 return false; 509 } 510 if (EV_CURRENT != header_->e_ident[EI_VERSION]) { 511 *error_msg = StringPrintf("Failed to find expected EI_VERSION value %d in %s, found %d", 512 EV_CURRENT, 513 file_->GetPath().c_str(), 514 header_->e_ident[EI_CLASS]); 515 return false; 516 } 517 if (ET_DYN != header_->e_type) { 518 *error_msg = StringPrintf("Failed to find expected e_type value %d in %s, found %d", 519 ET_DYN, 520 file_->GetPath().c_str(), 521 header_->e_type); 522 return false; 523 } 524 if (EV_CURRENT != header_->e_version) { 525 *error_msg = StringPrintf("Failed to find expected e_version value %d in %s, found %d", 526 EV_CURRENT, 527 file_->GetPath().c_str(), 528 header_->e_version); 529 return false; 530 } 531 if (0 != header_->e_entry) { 532 *error_msg = StringPrintf("Failed to find expected e_entry value %d in %s, found %d", 533 0, 534 file_->GetPath().c_str(), 535 static_cast<int32_t>(header_->e_entry)); 536 return false; 537 } 538 if (0 == header_->e_phoff) { 539 *error_msg = StringPrintf("Failed to find non-zero e_phoff value in %s", 540 file_->GetPath().c_str()); 541 return false; 542 } 543 if (0 == header_->e_shoff) { 544 *error_msg = StringPrintf("Failed to find non-zero e_shoff value in %s", 545 file_->GetPath().c_str()); 546 return false; 547 } 548 if (0 == header_->e_ehsize) { 549 *error_msg = StringPrintf("Failed to find non-zero e_ehsize value in %s", 550 file_->GetPath().c_str()); 551 return false; 552 } 553 if (0 == header_->e_phentsize) { 554 *error_msg = StringPrintf("Failed to find non-zero e_phentsize value in %s", 555 file_->GetPath().c_str()); 556 return false; 557 } 558 if (0 == header_->e_phnum) { 559 *error_msg = StringPrintf("Failed to find non-zero e_phnum value in %s", 560 file_->GetPath().c_str()); 561 return false; 562 } 563 if (0 == header_->e_shentsize) { 564 *error_msg = StringPrintf("Failed to find non-zero e_shentsize value in %s", 565 file_->GetPath().c_str()); 566 return false; 567 } 568 if (0 == header_->e_shnum) { 569 *error_msg = StringPrintf("Failed to find non-zero e_shnum value in %s", 570 file_->GetPath().c_str()); 571 return false; 572 } 573 if (0 == header_->e_shstrndx) { 574 *error_msg = StringPrintf("Failed to find non-zero e_shstrndx value in %s", 575 file_->GetPath().c_str()); 576 return false; 577 } 578 if (header_->e_shstrndx >= header_->e_shnum) { 579 *error_msg = StringPrintf("Failed to find e_shnum value %d less than %d in %s", 580 header_->e_shstrndx, 581 header_->e_shnum, 582 file_->GetPath().c_str()); 583 return false; 584 } 585 586 if (!program_header_only_) { 587 if (header_->e_phoff >= Size()) { 588 *error_msg = StringPrintf("Failed to find e_phoff value %" PRIu64 " less than %zd in %s", 589 static_cast<uint64_t>(header_->e_phoff), 590 Size(), 591 file_->GetPath().c_str()); 592 return false; 593 } 594 if (header_->e_shoff >= Size()) { 595 *error_msg = StringPrintf("Failed to find e_shoff value %" PRIu64 " less than %zd in %s", 596 static_cast<uint64_t>(header_->e_shoff), 597 Size(), 598 file_->GetPath().c_str()); 599 return false; 600 } 601 } 602 return true; 603 } 604 605 template <typename ElfTypes> 606 typename ElfTypes::Ehdr& ElfFileImpl<ElfTypes>::GetHeader() const { 607 CHECK(header_ != nullptr); // Header has been checked in SetMap. This is a sanity check. 608 return *header_; 609 } 610 611 template <typename ElfTypes> 612 uint8_t* ElfFileImpl<ElfTypes>::GetProgramHeadersStart() const { 613 CHECK(program_headers_start_ != nullptr); // Header has been set in Setup. This is a sanity 614 // check. 615 return program_headers_start_; 616 } 617 618 template <typename ElfTypes> 619 uint8_t* ElfFileImpl<ElfTypes>::GetSectionHeadersStart() const { 620 CHECK(!program_header_only_); // Only used in "full" mode. 621 CHECK(section_headers_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. 622 return section_headers_start_; 623 } 624 625 template <typename ElfTypes> 626 typename ElfTypes::Phdr& ElfFileImpl<ElfTypes>::GetDynamicProgramHeader() const { 627 CHECK(dynamic_program_header_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. 628 return *dynamic_program_header_; 629 } 630 631 template <typename ElfTypes> 632 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::GetDynamicSectionStart() const { 633 CHECK(dynamic_section_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. 634 return dynamic_section_start_; 635 } 636 637 template <typename ElfTypes> 638 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbolSectionStart( 639 Elf_Word section_type) const { 640 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; 641 switch (section_type) { 642 case SHT_SYMTAB: { 643 return symtab_section_start_; 644 break; 645 } 646 case SHT_DYNSYM: { 647 return dynsym_section_start_; 648 break; 649 } 650 default: { 651 LOG(FATAL) << section_type; 652 return nullptr; 653 } 654 } 655 } 656 657 template <typename ElfTypes> 658 const char* ElfFileImpl<ElfTypes>::GetStringSectionStart( 659 Elf_Word section_type) const { 660 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; 661 switch (section_type) { 662 case SHT_SYMTAB: { 663 return strtab_section_start_; 664 } 665 case SHT_DYNSYM: { 666 return dynstr_section_start_; 667 } 668 default: { 669 LOG(FATAL) << section_type; 670 return nullptr; 671 } 672 } 673 } 674 675 template <typename ElfTypes> 676 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Word section_type, 677 Elf_Word i) const { 678 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; 679 if (i == 0) { 680 return nullptr; 681 } 682 const char* string_section_start = GetStringSectionStart(section_type); 683 if (string_section_start == nullptr) { 684 return nullptr; 685 } 686 return string_section_start + i; 687 } 688 689 // WARNING: The following methods do not check for an error condition (non-existent hash section). 690 // It is the caller's job to do this. 691 692 template <typename ElfTypes> 693 typename ElfTypes::Word* ElfFileImpl<ElfTypes>::GetHashSectionStart() const { 694 return hash_section_start_; 695 } 696 697 template <typename ElfTypes> 698 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucketNum() const { 699 return GetHashSectionStart()[0]; 700 } 701 702 template <typename ElfTypes> 703 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChainNum() const { 704 return GetHashSectionStart()[1]; 705 } 706 707 template <typename ElfTypes> 708 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucket(size_t i, bool* ok) const { 709 if (i >= GetHashBucketNum()) { 710 *ok = false; 711 return 0; 712 } 713 *ok = true; 714 // 0 is nbucket, 1 is nchain 715 return GetHashSectionStart()[2 + i]; 716 } 717 718 template <typename ElfTypes> 719 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChain(size_t i, bool* ok) const { 720 if (i >= GetHashChainNum()) { 721 *ok = false; 722 return 0; 723 } 724 *ok = true; 725 // 0 is nbucket, 1 is nchain, & chains are after buckets 726 return GetHashSectionStart()[2 + GetHashBucketNum() + i]; 727 } 728 729 template <typename ElfTypes> 730 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetProgramHeaderNum() const { 731 return GetHeader().e_phnum; 732 } 733 734 template <typename ElfTypes> 735 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::GetProgramHeader(Elf_Word i) const { 736 CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath(); // Sanity check for caller. 737 uint8_t* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize); 738 if (program_header >= End()) { 739 return nullptr; // Failure condition. 740 } 741 return reinterpret_cast<Elf_Phdr*>(program_header); 742 } 743 744 template <typename ElfTypes> 745 typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::FindProgamHeaderByType(Elf_Word type) const { 746 for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { 747 Elf_Phdr* program_header = GetProgramHeader(i); 748 if (program_header->p_type == type) { 749 return program_header; 750 } 751 } 752 return nullptr; 753 } 754 755 template <typename ElfTypes> 756 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSectionHeaderNum() const { 757 return GetHeader().e_shnum; 758 } 759 760 template <typename ElfTypes> 761 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionHeader(Elf_Word i) const { 762 // Can only access arbitrary sections when we have the whole file, not just program header. 763 // Even if we Load(), it doesn't bring in all the sections. 764 CHECK(!program_header_only_) << file_->GetPath(); 765 if (i >= GetSectionHeaderNum()) { 766 return nullptr; // Failure condition. 767 } 768 uint8_t* section_header = GetSectionHeadersStart() + (i * GetHeader().e_shentsize); 769 if (section_header >= End()) { 770 return nullptr; // Failure condition. 771 } 772 return reinterpret_cast<Elf_Shdr*>(section_header); 773 } 774 775 template <typename ElfTypes> 776 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByType(Elf_Word type) const { 777 // Can only access arbitrary sections when we have the whole file, not just program header. 778 // We could change this to switch on known types if they were detected during loading. 779 CHECK(!program_header_only_) << file_->GetPath(); 780 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 781 Elf_Shdr* section_header = GetSectionHeader(i); 782 if (section_header->sh_type == type) { 783 return section_header; 784 } 785 } 786 return nullptr; 787 } 788 789 // from bionic 790 static unsigned elfhash(const char *_name) { 791 const unsigned char *name = (const unsigned char *) _name; 792 unsigned h = 0, g; 793 794 while (*name) { 795 h = (h << 4) + *name++; 796 g = h & 0xf0000000; 797 h ^= g; 798 h ^= g >> 24; 799 } 800 return h; 801 } 802 803 template <typename ElfTypes> 804 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionNameStringSection() const { 805 return GetSectionHeader(GetHeader().e_shstrndx); 806 } 807 808 template <typename ElfTypes> 809 const uint8_t* ElfFileImpl<ElfTypes>::FindDynamicSymbolAddress( 810 const std::string& symbol_name) const { 811 // Check that we have a hash section. 812 if (GetHashSectionStart() == nullptr) { 813 return nullptr; // Failure condition. 814 } 815 const Elf_Sym* sym = FindDynamicSymbol(symbol_name); 816 if (sym != nullptr) { 817 // TODO: we need to change this to calculate base_address_ in ::Open, 818 // otherwise it will be wrongly 0 if ::Load has not yet been called. 819 return base_address_ + sym->st_value; 820 } else { 821 return nullptr; 822 } 823 } 824 825 // WARNING: Only called from FindDynamicSymbolAddress. Elides check for hash section. 826 template <typename ElfTypes> 827 const typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindDynamicSymbol( 828 const std::string& symbol_name) const { 829 if (GetHashBucketNum() == 0) { 830 // No dynamic symbols at all. 831 return nullptr; 832 } 833 Elf_Word hash = elfhash(symbol_name.c_str()); 834 Elf_Word bucket_index = hash % GetHashBucketNum(); 835 bool ok; 836 Elf_Word symbol_and_chain_index = GetHashBucket(bucket_index, &ok); 837 if (!ok) { 838 return nullptr; 839 } 840 while (symbol_and_chain_index != 0 /* STN_UNDEF */) { 841 Elf_Sym* symbol = GetSymbol(SHT_DYNSYM, symbol_and_chain_index); 842 if (symbol == nullptr) { 843 return nullptr; // Failure condition. 844 } 845 const char* name = GetString(SHT_DYNSYM, symbol->st_name); 846 if (symbol_name == name) { 847 return symbol; 848 } 849 symbol_and_chain_index = GetHashChain(symbol_and_chain_index, &ok); 850 if (!ok) { 851 return nullptr; 852 } 853 } 854 return nullptr; 855 } 856 857 template <typename ElfTypes> 858 bool ElfFileImpl<ElfTypes>::IsSymbolSectionType(Elf_Word section_type) { 859 return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM)); 860 } 861 862 template <typename ElfTypes> 863 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSymbolNum(Elf_Shdr& section_header) const { 864 CHECK(IsSymbolSectionType(section_header.sh_type)) 865 << file_->GetPath() << " " << section_header.sh_type; 866 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath(); 867 return section_header.sh_size / section_header.sh_entsize; 868 } 869 870 template <typename ElfTypes> 871 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbol(Elf_Word section_type, Elf_Word i) const { 872 Elf_Sym* sym_start = GetSymbolSectionStart(section_type); 873 if (sym_start == nullptr) { 874 return nullptr; 875 } 876 return sym_start + i; 877 } 878 879 template <typename ElfTypes> 880 typename ElfFileImpl<ElfTypes>::SymbolTable** 881 ElfFileImpl<ElfTypes>::GetSymbolTable(Elf_Word section_type) { 882 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; 883 switch (section_type) { 884 case SHT_SYMTAB: { 885 return &symtab_symbol_table_; 886 } 887 case SHT_DYNSYM: { 888 return &dynsym_symbol_table_; 889 } 890 default: { 891 LOG(FATAL) << section_type; 892 return nullptr; 893 } 894 } 895 } 896 897 template <typename ElfTypes> 898 typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindSymbolByName( 899 Elf_Word section_type, const std::string& symbol_name, bool build_map) { 900 CHECK(!program_header_only_) << file_->GetPath(); 901 CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; 902 903 SymbolTable** symbol_table = GetSymbolTable(section_type); 904 if (*symbol_table != nullptr || build_map) { 905 if (*symbol_table == nullptr) { 906 DCHECK(build_map); 907 *symbol_table = new SymbolTable; 908 Elf_Shdr* symbol_section = FindSectionByType(section_type); 909 if (symbol_section == nullptr) { 910 return nullptr; // Failure condition. 911 } 912 Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link); 913 if (string_section == nullptr) { 914 return nullptr; // Failure condition. 915 } 916 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) { 917 Elf_Sym* symbol = GetSymbol(section_type, i); 918 if (symbol == nullptr) { 919 return nullptr; // Failure condition. 920 } 921 unsigned char type = (sizeof(Elf_Addr) == sizeof(Elf64_Addr)) 922 ? ELF64_ST_TYPE(symbol->st_info) 923 : ELF32_ST_TYPE(symbol->st_info); 924 if (type == STT_NOTYPE) { 925 continue; 926 } 927 const char* name = GetString(*string_section, symbol->st_name); 928 if (name == nullptr) { 929 continue; 930 } 931 std::pair<typename SymbolTable::iterator, bool> result = 932 (*symbol_table)->insert(std::make_pair(name, symbol)); 933 if (!result.second) { 934 // If a duplicate, make sure it has the same logical value. Seen on x86. 935 if ((symbol->st_value != result.first->second->st_value) || 936 (symbol->st_size != result.first->second->st_size) || 937 (symbol->st_info != result.first->second->st_info) || 938 (symbol->st_other != result.first->second->st_other) || 939 (symbol->st_shndx != result.first->second->st_shndx)) { 940 return nullptr; // Failure condition. 941 } 942 } 943 } 944 } 945 CHECK(*symbol_table != nullptr); 946 typename SymbolTable::const_iterator it = (*symbol_table)->find(symbol_name); 947 if (it == (*symbol_table)->end()) { 948 return nullptr; 949 } 950 return it->second; 951 } 952 953 // Fall back to linear search 954 Elf_Shdr* symbol_section = FindSectionByType(section_type); 955 if (symbol_section == nullptr) { 956 return nullptr; 957 } 958 Elf_Shdr* string_section = GetSectionHeader(symbol_section->sh_link); 959 if (string_section == nullptr) { 960 return nullptr; 961 } 962 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) { 963 Elf_Sym* symbol = GetSymbol(section_type, i); 964 if (symbol == nullptr) { 965 return nullptr; // Failure condition. 966 } 967 const char* name = GetString(*string_section, symbol->st_name); 968 if (name == nullptr) { 969 continue; 970 } 971 if (symbol_name == name) { 972 return symbol; 973 } 974 } 975 return nullptr; 976 } 977 978 template <typename ElfTypes> 979 typename ElfTypes::Addr ElfFileImpl<ElfTypes>::FindSymbolAddress( 980 Elf_Word section_type, const std::string& symbol_name, bool build_map) { 981 Elf_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map); 982 if (symbol == nullptr) { 983 return 0; 984 } 985 return symbol->st_value; 986 } 987 988 template <typename ElfTypes> 989 const char* ElfFileImpl<ElfTypes>::GetString(Elf_Shdr& string_section, 990 Elf_Word i) const { 991 CHECK(!program_header_only_) << file_->GetPath(); 992 // TODO: remove this static_cast from enum when using -std=gnu++0x 993 if (static_cast<Elf_Word>(SHT_STRTAB) != string_section.sh_type) { 994 return nullptr; // Failure condition. 995 } 996 if (i >= string_section.sh_size) { 997 return nullptr; 998 } 999 if (i == 0) { 1000 return nullptr; 1001 } 1002 uint8_t* strings = Begin() + string_section.sh_offset; 1003 uint8_t* string = strings + i; 1004 if (string >= End()) { 1005 return nullptr; 1006 } 1007 return reinterpret_cast<const char*>(string); 1008 } 1009 1010 template <typename ElfTypes> 1011 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetDynamicNum() const { 1012 return GetDynamicProgramHeader().p_filesz / sizeof(Elf_Dyn); 1013 } 1014 1015 template <typename ElfTypes> 1016 typename ElfTypes::Dyn& ElfFileImpl<ElfTypes>::GetDynamic(Elf_Word i) const { 1017 CHECK_LT(i, GetDynamicNum()) << file_->GetPath(); 1018 return *(GetDynamicSectionStart() + i); 1019 } 1020 1021 template <typename ElfTypes> 1022 typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::FindDynamicByType(Elf_Sword type) const { 1023 for (Elf_Word i = 0; i < GetDynamicNum(); i++) { 1024 Elf_Dyn* dyn = &GetDynamic(i); 1025 if (dyn->d_tag == type) { 1026 return dyn; 1027 } 1028 } 1029 return nullptr; 1030 } 1031 1032 template <typename ElfTypes> 1033 typename ElfTypes::Word ElfFileImpl<ElfTypes>::FindDynamicValueByType(Elf_Sword type) const { 1034 Elf_Dyn* dyn = FindDynamicByType(type); 1035 if (dyn == nullptr) { 1036 return 0; 1037 } else { 1038 return dyn->d_un.d_val; 1039 } 1040 } 1041 1042 template <typename ElfTypes> 1043 typename ElfTypes::Rel* ElfFileImpl<ElfTypes>::GetRelSectionStart(Elf_Shdr& section_header) const { 1044 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1045 return reinterpret_cast<Elf_Rel*>(Begin() + section_header.sh_offset); 1046 } 1047 1048 template <typename ElfTypes> 1049 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelNum(Elf_Shdr& section_header) const { 1050 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1051 CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath(); 1052 return section_header.sh_size / section_header.sh_entsize; 1053 } 1054 1055 template <typename ElfTypes> 1056 typename ElfTypes::Rel& ElfFileImpl<ElfTypes>::GetRel(Elf_Shdr& section_header, Elf_Word i) const { 1057 CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1058 CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath(); 1059 return *(GetRelSectionStart(section_header) + i); 1060 } 1061 1062 template <typename ElfTypes> 1063 typename ElfTypes::Rela* ElfFileImpl<ElfTypes>::GetRelaSectionStart(Elf_Shdr& section_header) const { 1064 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1065 return reinterpret_cast<Elf_Rela*>(Begin() + section_header.sh_offset); 1066 } 1067 1068 template <typename ElfTypes> 1069 typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelaNum(Elf_Shdr& section_header) const { 1070 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1071 return section_header.sh_size / section_header.sh_entsize; 1072 } 1073 1074 template <typename ElfTypes> 1075 typename ElfTypes::Rela& ElfFileImpl<ElfTypes>::GetRela(Elf_Shdr& section_header, Elf_Word i) const { 1076 CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; 1077 CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath(); 1078 return *(GetRelaSectionStart(section_header) + i); 1079 } 1080 1081 // Base on bionic phdr_table_get_load_size 1082 template <typename ElfTypes> 1083 bool ElfFileImpl<ElfTypes>::GetLoadedSize(size_t* size, std::string* error_msg) const { 1084 Elf_Addr min_vaddr = static_cast<Elf_Addr>(-1); 1085 Elf_Addr max_vaddr = 0u; 1086 for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { 1087 Elf_Phdr* program_header = GetProgramHeader(i); 1088 if (program_header->p_type != PT_LOAD) { 1089 continue; 1090 } 1091 Elf_Addr begin_vaddr = program_header->p_vaddr; 1092 if (begin_vaddr < min_vaddr) { 1093 min_vaddr = begin_vaddr; 1094 } 1095 Elf_Addr end_vaddr = program_header->p_vaddr + program_header->p_memsz; 1096 if (UNLIKELY(begin_vaddr > end_vaddr)) { 1097 std::ostringstream oss; 1098 oss << "Program header #" << i << " has overflow in p_vaddr+p_memsz: 0x" << std::hex 1099 << program_header->p_vaddr << "+0x" << program_header->p_memsz << "=0x" << end_vaddr 1100 << " in ELF file \"" << file_->GetPath() << "\""; 1101 *error_msg = oss.str(); 1102 *size = static_cast<size_t>(-1); 1103 return false; 1104 } 1105 if (end_vaddr > max_vaddr) { 1106 max_vaddr = end_vaddr; 1107 } 1108 } 1109 min_vaddr = RoundDown(min_vaddr, kPageSize); 1110 max_vaddr = RoundUp(max_vaddr, kPageSize); 1111 CHECK_LT(min_vaddr, max_vaddr) << file_->GetPath(); 1112 Elf_Addr loaded_size = max_vaddr - min_vaddr; 1113 // Check that the loaded_size fits in size_t. 1114 if (UNLIKELY(loaded_size > std::numeric_limits<size_t>::max())) { 1115 std::ostringstream oss; 1116 oss << "Loaded size is 0x" << std::hex << loaded_size << " but maximum size_t is 0x" 1117 << std::numeric_limits<size_t>::max() << " for ELF file \"" << file_->GetPath() << "\""; 1118 *error_msg = oss.str(); 1119 *size = static_cast<size_t>(-1); 1120 return false; 1121 } 1122 *size = loaded_size; 1123 return true; 1124 } 1125 1126 template <typename ElfTypes> 1127 bool ElfFileImpl<ElfTypes>::Load(bool executable, std::string* error_msg) { 1128 CHECK(program_header_only_) << file_->GetPath(); 1129 1130 if (executable) { 1131 InstructionSet elf_ISA = GetInstructionSetFromELF(GetHeader().e_machine, GetHeader().e_flags); 1132 if (elf_ISA != kRuntimeISA) { 1133 std::ostringstream oss; 1134 oss << "Expected ISA " << kRuntimeISA << " but found " << elf_ISA; 1135 *error_msg = oss.str(); 1136 return false; 1137 } 1138 } 1139 1140 bool reserved = false; 1141 for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { 1142 Elf_Phdr* program_header = GetProgramHeader(i); 1143 if (program_header == nullptr) { 1144 *error_msg = StringPrintf("No program header for entry %d in ELF file %s.", 1145 i, file_->GetPath().c_str()); 1146 return false; 1147 } 1148 1149 // Record .dynamic header information for later use 1150 if (program_header->p_type == PT_DYNAMIC) { 1151 dynamic_program_header_ = program_header; 1152 continue; 1153 } 1154 1155 // Not something to load, move on. 1156 if (program_header->p_type != PT_LOAD) { 1157 continue; 1158 } 1159 1160 // Found something to load. 1161 1162 // Before load the actual segments, reserve a contiguous chunk 1163 // of required size and address for all segments, but with no 1164 // permissions. We'll then carve that up with the proper 1165 // permissions as we load the actual segments. If p_vaddr is 1166 // non-zero, the segments require the specific address specified, 1167 // which either was specified in the file because we already set 1168 // base_address_ after the first zero segment). 1169 int64_t temp_file_length = file_->GetLength(); 1170 if (temp_file_length < 0) { 1171 errno = -temp_file_length; 1172 *error_msg = StringPrintf("Failed to get length of file: '%s' fd=%d: %s", 1173 file_->GetPath().c_str(), file_->Fd(), strerror(errno)); 1174 return false; 1175 } 1176 size_t file_length = static_cast<size_t>(temp_file_length); 1177 if (!reserved) { 1178 uint8_t* reserve_base = reinterpret_cast<uint8_t*>(program_header->p_vaddr); 1179 uint8_t* reserve_base_override = reserve_base; 1180 // Override the base (e.g. when compiling with --compile-pic) 1181 if (requested_base_ != nullptr) { 1182 reserve_base_override = requested_base_; 1183 } 1184 std::string reservation_name("ElfFile reservation for "); 1185 reservation_name += file_->GetPath(); 1186 size_t loaded_size; 1187 if (!GetLoadedSize(&loaded_size, error_msg)) { 1188 DCHECK(!error_msg->empty()); 1189 return false; 1190 } 1191 std::unique_ptr<MemMap> reserve(MemMap::MapAnonymous(reservation_name.c_str(), 1192 reserve_base_override, 1193 loaded_size, PROT_NONE, false, false, 1194 error_msg)); 1195 if (reserve.get() == nullptr) { 1196 *error_msg = StringPrintf("Failed to allocate %s: %s", 1197 reservation_name.c_str(), error_msg->c_str()); 1198 return false; 1199 } 1200 reserved = true; 1201 1202 // Base address is the difference of actual mapped location and the p_vaddr 1203 base_address_ = reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(reserve->Begin()) 1204 - reinterpret_cast<uintptr_t>(reserve_base)); 1205 // By adding the p_vaddr of a section/symbol to base_address_ we will always get the 1206 // dynamic memory address of where that object is actually mapped 1207 // 1208 // TODO: base_address_ needs to be calculated in ::Open, otherwise 1209 // FindDynamicSymbolAddress returns the wrong values until Load is called. 1210 segments_.push_back(reserve.release()); 1211 } 1212 // empty segment, nothing to map 1213 if (program_header->p_memsz == 0) { 1214 continue; 1215 } 1216 uint8_t* p_vaddr = base_address_ + program_header->p_vaddr; 1217 int prot = 0; 1218 if (executable && ((program_header->p_flags & PF_X) != 0)) { 1219 prot |= PROT_EXEC; 1220 } 1221 if ((program_header->p_flags & PF_W) != 0) { 1222 prot |= PROT_WRITE; 1223 } 1224 if ((program_header->p_flags & PF_R) != 0) { 1225 prot |= PROT_READ; 1226 } 1227 int flags = 0; 1228 if (writable_) { 1229 prot |= PROT_WRITE; 1230 flags |= MAP_SHARED; 1231 } else { 1232 flags |= MAP_PRIVATE; 1233 } 1234 if (program_header->p_filesz > program_header->p_memsz) { 1235 *error_msg = StringPrintf("Invalid p_filesz > p_memsz (%" PRIu64 " > %" PRIu64 "): %s", 1236 static_cast<uint64_t>(program_header->p_filesz), 1237 static_cast<uint64_t>(program_header->p_memsz), 1238 file_->GetPath().c_str()); 1239 return false; 1240 } 1241 if (program_header->p_filesz < program_header->p_memsz && 1242 !IsAligned<kPageSize>(program_header->p_filesz)) { 1243 *error_msg = StringPrintf("Unsupported unaligned p_filesz < p_memsz (%" PRIu64 1244 " < %" PRIu64 "): %s", 1245 static_cast<uint64_t>(program_header->p_filesz), 1246 static_cast<uint64_t>(program_header->p_memsz), 1247 file_->GetPath().c_str()); 1248 return false; 1249 } 1250 if (file_length < (program_header->p_offset + program_header->p_filesz)) { 1251 *error_msg = StringPrintf("File size of %zd bytes not large enough to contain ELF segment " 1252 "%d of %" PRIu64 " bytes: '%s'", file_length, i, 1253 static_cast<uint64_t>(program_header->p_offset + program_header->p_filesz), 1254 file_->GetPath().c_str()); 1255 return false; 1256 } 1257 if (program_header->p_filesz != 0u) { 1258 std::unique_ptr<MemMap> segment( 1259 MemMap::MapFileAtAddress(p_vaddr, 1260 program_header->p_filesz, 1261 prot, flags, file_->Fd(), 1262 program_header->p_offset, 1263 true, // implies MAP_FIXED 1264 file_->GetPath().c_str(), 1265 error_msg)); 1266 if (segment.get() == nullptr) { 1267 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s: %s", 1268 i, file_->GetPath().c_str(), error_msg->c_str()); 1269 return false; 1270 } 1271 if (segment->Begin() != p_vaddr) { 1272 *error_msg = StringPrintf("Failed to map ELF file segment %d from %s at expected address %p, " 1273 "instead mapped to %p", 1274 i, file_->GetPath().c_str(), p_vaddr, segment->Begin()); 1275 return false; 1276 } 1277 segments_.push_back(segment.release()); 1278 } 1279 if (program_header->p_filesz < program_header->p_memsz) { 1280 std::string name = StringPrintf("Zero-initialized segment %" PRIu64 " of ELF file %s", 1281 static_cast<uint64_t>(i), file_->GetPath().c_str()); 1282 std::unique_ptr<MemMap> segment( 1283 MemMap::MapAnonymous(name.c_str(), 1284 p_vaddr + program_header->p_filesz, 1285 program_header->p_memsz - program_header->p_filesz, 1286 prot, false, true /* reuse */, error_msg)); 1287 if (segment == nullptr) { 1288 *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s: %s", 1289 i, file_->GetPath().c_str(), error_msg->c_str()); 1290 return false; 1291 } 1292 if (segment->Begin() != p_vaddr) { 1293 *error_msg = StringPrintf("Failed to map zero-initialized ELF file segment %d from %s " 1294 "at expected address %p, instead mapped to %p", 1295 i, file_->GetPath().c_str(), p_vaddr, segment->Begin()); 1296 return false; 1297 } 1298 segments_.push_back(segment.release()); 1299 } 1300 } 1301 1302 // Now that we are done loading, .dynamic should be in memory to find .dynstr, .dynsym, .hash 1303 uint8_t* dsptr = base_address_ + GetDynamicProgramHeader().p_vaddr; 1304 if ((dsptr < Begin() || dsptr >= End()) && !ValidPointer(dsptr)) { 1305 *error_msg = StringPrintf("dynamic section address invalid in ELF file %s", 1306 file_->GetPath().c_str()); 1307 return false; 1308 } 1309 dynamic_section_start_ = reinterpret_cast<Elf_Dyn*>(dsptr); 1310 1311 for (Elf_Word i = 0; i < GetDynamicNum(); i++) { 1312 Elf_Dyn& elf_dyn = GetDynamic(i); 1313 uint8_t* d_ptr = base_address_ + elf_dyn.d_un.d_ptr; 1314 switch (elf_dyn.d_tag) { 1315 case DT_HASH: { 1316 if (!ValidPointer(d_ptr)) { 1317 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s", 1318 d_ptr, file_->GetPath().c_str()); 1319 return false; 1320 } 1321 hash_section_start_ = reinterpret_cast<Elf_Word*>(d_ptr); 1322 break; 1323 } 1324 case DT_STRTAB: { 1325 if (!ValidPointer(d_ptr)) { 1326 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s", 1327 d_ptr, file_->GetPath().c_str()); 1328 return false; 1329 } 1330 dynstr_section_start_ = reinterpret_cast<char*>(d_ptr); 1331 break; 1332 } 1333 case DT_SYMTAB: { 1334 if (!ValidPointer(d_ptr)) { 1335 *error_msg = StringPrintf("DT_HASH value %p does not refer to a loaded ELF segment of %s", 1336 d_ptr, file_->GetPath().c_str()); 1337 return false; 1338 } 1339 dynsym_section_start_ = reinterpret_cast<Elf_Sym*>(d_ptr); 1340 break; 1341 } 1342 case DT_NULL: { 1343 if (GetDynamicNum() != i+1) { 1344 *error_msg = StringPrintf("DT_NULL found after %d .dynamic entries, " 1345 "expected %d as implied by size of PT_DYNAMIC segment in %s", 1346 i + 1, GetDynamicNum(), file_->GetPath().c_str()); 1347 return false; 1348 } 1349 break; 1350 } 1351 } 1352 } 1353 1354 // Check for the existence of some sections. 1355 if (!CheckSectionsExist(error_msg)) { 1356 return false; 1357 } 1358 1359 // Use GDB JIT support to do stack backtrace, etc. 1360 if (executable) { 1361 GdbJITSupport(); 1362 } 1363 1364 return true; 1365 } 1366 1367 template <typename ElfTypes> 1368 bool ElfFileImpl<ElfTypes>::ValidPointer(const uint8_t* start) const { 1369 for (size_t i = 0; i < segments_.size(); ++i) { 1370 const MemMap* segment = segments_[i]; 1371 if (segment->Begin() <= start && start < segment->End()) { 1372 return true; 1373 } 1374 } 1375 return false; 1376 } 1377 1378 1379 template <typename ElfTypes> 1380 typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName( 1381 const std::string& name) const { 1382 CHECK(!program_header_only_); 1383 Elf_Shdr* shstrtab_sec = GetSectionNameStringSection(); 1384 if (shstrtab_sec == nullptr) { 1385 return nullptr; 1386 } 1387 for (uint32_t i = 0; i < GetSectionHeaderNum(); i++) { 1388 Elf_Shdr* shdr = GetSectionHeader(i); 1389 if (shdr == nullptr) { 1390 return nullptr; 1391 } 1392 const char* sec_name = GetString(*shstrtab_sec, shdr->sh_name); 1393 if (sec_name == nullptr) { 1394 continue; 1395 } 1396 if (name == sec_name) { 1397 return shdr; 1398 } 1399 } 1400 return nullptr; 1401 } 1402 1403 template <typename ElfTypes> 1404 bool ElfFileImpl<ElfTypes>::FixupDebugSections(Elf_Addr base_address_delta) { 1405 if (base_address_delta == 0) { 1406 return true; 1407 } 1408 return ApplyOatPatchesTo(".debug_frame", base_address_delta) && 1409 ApplyOatPatchesTo(".debug_info", base_address_delta) && 1410 ApplyOatPatchesTo(".debug_line", base_address_delta); 1411 } 1412 1413 template <typename ElfTypes> 1414 bool ElfFileImpl<ElfTypes>::ApplyOatPatchesTo( 1415 const char* target_section_name, Elf_Addr delta) { 1416 auto target_section = FindSectionByName(target_section_name); 1417 if (target_section == nullptr) { 1418 return true; 1419 } 1420 std::string patches_name = target_section_name + std::string(".oat_patches"); 1421 auto patches_section = FindSectionByName(patches_name.c_str()); 1422 if (patches_section == nullptr) { 1423 LOG(ERROR) << patches_name << " section not found."; 1424 return false; 1425 } 1426 if (patches_section->sh_type != SHT_OAT_PATCH) { 1427 LOG(ERROR) << "Unexpected type of " << patches_name; 1428 return false; 1429 } 1430 ApplyOatPatches( 1431 Begin() + patches_section->sh_offset, 1432 Begin() + patches_section->sh_offset + patches_section->sh_size, 1433 delta, 1434 Begin() + target_section->sh_offset, 1435 Begin() + target_section->sh_offset + target_section->sh_size); 1436 return true; 1437 } 1438 1439 // Apply LEB128 encoded patches to given section. 1440 template <typename ElfTypes> 1441 void ElfFileImpl<ElfTypes>::ApplyOatPatches( 1442 const uint8_t* patches, const uint8_t* patches_end, Elf_Addr delta, 1443 uint8_t* to_patch, const uint8_t* to_patch_end) { 1444 typedef __attribute__((__aligned__(1))) Elf_Addr UnalignedAddress; 1445 while (patches < patches_end) { 1446 to_patch += DecodeUnsignedLeb128(&patches); 1447 DCHECK_LE(patches, patches_end) << "Unexpected end of patch list."; 1448 DCHECK_LT(to_patch, to_patch_end) << "Patch past the end of section."; 1449 *reinterpret_cast<UnalignedAddress*>(to_patch) += delta; 1450 } 1451 } 1452 1453 template <typename ElfTypes> 1454 void ElfFileImpl<ElfTypes>::GdbJITSupport() { 1455 // We only get here if we only are mapping the program header. 1456 DCHECK(program_header_only_); 1457 1458 // Well, we need the whole file to do this. 1459 std::string error_msg; 1460 // Make it MAP_PRIVATE so we can just give it to gdb if all the necessary 1461 // sections are there. 1462 std::unique_ptr<ElfFileImpl<ElfTypes>> all_ptr( 1463 Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg)); 1464 if (all_ptr.get() == nullptr) { 1465 return; 1466 } 1467 ElfFileImpl<ElfTypes>& all = *all_ptr; 1468 1469 // We need the eh_frame for gdb but debug info might be present without it. 1470 const Elf_Shdr* eh_frame = all.FindSectionByName(".eh_frame"); 1471 if (eh_frame == nullptr) { 1472 return; 1473 } 1474 1475 // Do we have interesting sections? 1476 // We need to add in a strtab and symtab to the image. 1477 // all is MAP_PRIVATE so it can be written to freely. 1478 // We also already have strtab and symtab so we are fine there. 1479 Elf_Ehdr& elf_hdr = all.GetHeader(); 1480 elf_hdr.e_entry = 0; 1481 elf_hdr.e_phoff = 0; 1482 elf_hdr.e_phnum = 0; 1483 elf_hdr.e_phentsize = 0; 1484 elf_hdr.e_type = ET_EXEC; 1485 1486 // Since base_address_ is 0 if we are actually loaded at a known address (i.e. this is boot.oat) 1487 // and the actual address stuff starts at in regular files this is good. 1488 if (!all.FixupDebugSections(reinterpret_cast<intptr_t>(base_address_))) { 1489 LOG(ERROR) << "Failed to load GDB data"; 1490 return; 1491 } 1492 1493 jit_gdb_entry_ = CreateCodeEntry(all.Begin(), all.Size()); 1494 gdb_file_mapping_.reset(all_ptr.release()); 1495 } 1496 1497 template <typename ElfTypes> 1498 bool ElfFileImpl<ElfTypes>::Strip(std::string* error_msg) { 1499 // ELF files produced by MCLinker look roughly like this 1500 // 1501 // +------------+ 1502 // | Elf_Ehdr | contains number of Elf_Shdr and offset to first 1503 // +------------+ 1504 // | Elf_Phdr | program headers 1505 // | Elf_Phdr | 1506 // | ... | 1507 // | Elf_Phdr | 1508 // +------------+ 1509 // | section | mixture of needed and unneeded sections 1510 // +------------+ 1511 // | section | 1512 // +------------+ 1513 // | ... | 1514 // +------------+ 1515 // | section | 1516 // +------------+ 1517 // | Elf_Shdr | section headers 1518 // | Elf_Shdr | 1519 // | ... | contains offset to section start 1520 // | Elf_Shdr | 1521 // +------------+ 1522 // 1523 // To strip: 1524 // - leave the Elf_Ehdr and Elf_Phdr values in place. 1525 // - walk the sections making a new set of Elf_Shdr section headers for what we want to keep 1526 // - move the sections are keeping up to fill in gaps of sections we want to strip 1527 // - write new Elf_Shdr section headers to end of file, updating Elf_Ehdr 1528 // - truncate rest of file 1529 // 1530 1531 std::vector<Elf_Shdr> section_headers; 1532 std::vector<Elf_Word> section_headers_original_indexes; 1533 section_headers.reserve(GetSectionHeaderNum()); 1534 1535 1536 Elf_Shdr* string_section = GetSectionNameStringSection(); 1537 CHECK(string_section != nullptr); 1538 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 1539 Elf_Shdr* sh = GetSectionHeader(i); 1540 CHECK(sh != nullptr); 1541 const char* name = GetString(*string_section, sh->sh_name); 1542 if (name == nullptr) { 1543 CHECK_EQ(0U, i); 1544 section_headers.push_back(*sh); 1545 section_headers_original_indexes.push_back(0); 1546 continue; 1547 } 1548 if (StartsWith(name, ".debug") 1549 || (strcmp(name, ".strtab") == 0) 1550 || (strcmp(name, ".symtab") == 0)) { 1551 continue; 1552 } 1553 section_headers.push_back(*sh); 1554 section_headers_original_indexes.push_back(i); 1555 } 1556 CHECK_NE(0U, section_headers.size()); 1557 CHECK_EQ(section_headers.size(), section_headers_original_indexes.size()); 1558 1559 // section 0 is the null section, sections start at offset of first section 1560 CHECK(GetSectionHeader(1) != nullptr); 1561 Elf_Off offset = GetSectionHeader(1)->sh_offset; 1562 for (size_t i = 1; i < section_headers.size(); i++) { 1563 Elf_Shdr& new_sh = section_headers[i]; 1564 Elf_Shdr* old_sh = GetSectionHeader(section_headers_original_indexes[i]); 1565 CHECK(old_sh != nullptr); 1566 CHECK_EQ(new_sh.sh_name, old_sh->sh_name); 1567 if (old_sh->sh_addralign > 1) { 1568 offset = RoundUp(offset, old_sh->sh_addralign); 1569 } 1570 if (old_sh->sh_offset == offset) { 1571 // already in place 1572 offset += old_sh->sh_size; 1573 continue; 1574 } 1575 // shift section earlier 1576 memmove(Begin() + offset, 1577 Begin() + old_sh->sh_offset, 1578 old_sh->sh_size); 1579 new_sh.sh_offset = offset; 1580 offset += old_sh->sh_size; 1581 } 1582 1583 Elf_Off shoff = offset; 1584 size_t section_headers_size_in_bytes = section_headers.size() * sizeof(Elf_Shdr); 1585 memcpy(Begin() + offset, §ion_headers[0], section_headers_size_in_bytes); 1586 offset += section_headers_size_in_bytes; 1587 1588 GetHeader().e_shnum = section_headers.size(); 1589 GetHeader().e_shoff = shoff; 1590 int result = ftruncate(file_->Fd(), offset); 1591 if (result != 0) { 1592 *error_msg = StringPrintf("Failed to truncate while stripping ELF file: '%s': %s", 1593 file_->GetPath().c_str(), strerror(errno)); 1594 return false; 1595 } 1596 return true; 1597 } 1598 1599 static const bool DEBUG_FIXUP = false; 1600 1601 template <typename ElfTypes> 1602 bool ElfFileImpl<ElfTypes>::Fixup(Elf_Addr base_address) { 1603 if (!FixupDynamic(base_address)) { 1604 LOG(WARNING) << "Failed to fixup .dynamic in " << file_->GetPath(); 1605 return false; 1606 } 1607 if (!FixupSectionHeaders(base_address)) { 1608 LOG(WARNING) << "Failed to fixup section headers in " << file_->GetPath(); 1609 return false; 1610 } 1611 if (!FixupProgramHeaders(base_address)) { 1612 LOG(WARNING) << "Failed to fixup program headers in " << file_->GetPath(); 1613 return false; 1614 } 1615 if (!FixupSymbols(base_address, true)) { 1616 LOG(WARNING) << "Failed to fixup .dynsym in " << file_->GetPath(); 1617 return false; 1618 } 1619 if (!FixupSymbols(base_address, false)) { 1620 LOG(WARNING) << "Failed to fixup .symtab in " << file_->GetPath(); 1621 return false; 1622 } 1623 if (!FixupRelocations(base_address)) { 1624 LOG(WARNING) << "Failed to fixup .rel.dyn in " << file_->GetPath(); 1625 return false; 1626 } 1627 static_assert(sizeof(Elf_Off) >= sizeof(base_address), "Potentially losing precision."); 1628 if (!FixupDebugSections(static_cast<Elf_Off>(base_address))) { 1629 LOG(WARNING) << "Failed to fixup debug sections in " << file_->GetPath(); 1630 return false; 1631 } 1632 return true; 1633 } 1634 1635 template <typename ElfTypes> 1636 bool ElfFileImpl<ElfTypes>::FixupDynamic(Elf_Addr base_address) { 1637 for (Elf_Word i = 0; i < GetDynamicNum(); i++) { 1638 Elf_Dyn& elf_dyn = GetDynamic(i); 1639 Elf_Word d_tag = elf_dyn.d_tag; 1640 if (IsDynamicSectionPointer(d_tag, GetHeader().e_machine)) { 1641 Elf_Addr d_ptr = elf_dyn.d_un.d_ptr; 1642 if (DEBUG_FIXUP) { 1643 LOG(INFO) << StringPrintf("In %s moving Elf_Dyn[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1644 GetFile().GetPath().c_str(), i, 1645 static_cast<uint64_t>(d_ptr), 1646 static_cast<uint64_t>(d_ptr + base_address)); 1647 } 1648 d_ptr += base_address; 1649 elf_dyn.d_un.d_ptr = d_ptr; 1650 } 1651 } 1652 return true; 1653 } 1654 1655 template <typename ElfTypes> 1656 bool ElfFileImpl<ElfTypes>::FixupSectionHeaders(Elf_Addr base_address) { 1657 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 1658 Elf_Shdr* sh = GetSectionHeader(i); 1659 CHECK(sh != nullptr); 1660 // 0 implies that the section will not exist in the memory of the process 1661 if (sh->sh_addr == 0) { 1662 continue; 1663 } 1664 if (DEBUG_FIXUP) { 1665 LOG(INFO) << StringPrintf("In %s moving Elf_Shdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1666 GetFile().GetPath().c_str(), i, 1667 static_cast<uint64_t>(sh->sh_addr), 1668 static_cast<uint64_t>(sh->sh_addr + base_address)); 1669 } 1670 sh->sh_addr += base_address; 1671 } 1672 return true; 1673 } 1674 1675 template <typename ElfTypes> 1676 bool ElfFileImpl<ElfTypes>::FixupProgramHeaders(Elf_Addr base_address) { 1677 // TODO: ELFObjectFile doesn't have give to Elf_Phdr, so we do that ourselves for now. 1678 for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { 1679 Elf_Phdr* ph = GetProgramHeader(i); 1680 CHECK(ph != nullptr); 1681 CHECK_EQ(ph->p_vaddr, ph->p_paddr) << GetFile().GetPath() << " i=" << i; 1682 CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1)))) 1683 << GetFile().GetPath() << " i=" << i; 1684 if (DEBUG_FIXUP) { 1685 LOG(INFO) << StringPrintf("In %s moving Elf_Phdr[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1686 GetFile().GetPath().c_str(), i, 1687 static_cast<uint64_t>(ph->p_vaddr), 1688 static_cast<uint64_t>(ph->p_vaddr + base_address)); 1689 } 1690 ph->p_vaddr += base_address; 1691 ph->p_paddr += base_address; 1692 CHECK((ph->p_align == 0) || (0 == ((ph->p_vaddr - ph->p_offset) & (ph->p_align - 1)))) 1693 << GetFile().GetPath() << " i=" << i; 1694 } 1695 return true; 1696 } 1697 1698 template <typename ElfTypes> 1699 bool ElfFileImpl<ElfTypes>::FixupSymbols(Elf_Addr base_address, bool dynamic) { 1700 Elf_Word section_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB; 1701 // TODO: Unfortunate ELFObjectFile has protected symbol access, so use ElfFile 1702 Elf_Shdr* symbol_section = FindSectionByType(section_type); 1703 if (symbol_section == nullptr) { 1704 // file is missing optional .symtab 1705 CHECK(!dynamic) << GetFile().GetPath(); 1706 return true; 1707 } 1708 for (uint32_t i = 0; i < GetSymbolNum(*symbol_section); i++) { 1709 Elf_Sym* symbol = GetSymbol(section_type, i); 1710 CHECK(symbol != nullptr); 1711 if (symbol->st_value != 0) { 1712 if (DEBUG_FIXUP) { 1713 LOG(INFO) << StringPrintf("In %s moving Elf_Sym[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1714 GetFile().GetPath().c_str(), i, 1715 static_cast<uint64_t>(symbol->st_value), 1716 static_cast<uint64_t>(symbol->st_value + base_address)); 1717 } 1718 symbol->st_value += base_address; 1719 } 1720 } 1721 return true; 1722 } 1723 1724 template <typename ElfTypes> 1725 bool ElfFileImpl<ElfTypes>::FixupRelocations(Elf_Addr base_address) { 1726 for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { 1727 Elf_Shdr* sh = GetSectionHeader(i); 1728 CHECK(sh != nullptr); 1729 if (sh->sh_type == SHT_REL) { 1730 for (uint32_t j = 0; j < GetRelNum(*sh); j++) { 1731 Elf_Rel& rel = GetRel(*sh, j); 1732 if (DEBUG_FIXUP) { 1733 LOG(INFO) << StringPrintf("In %s moving Elf_Rel[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1734 GetFile().GetPath().c_str(), j, 1735 static_cast<uint64_t>(rel.r_offset), 1736 static_cast<uint64_t>(rel.r_offset + base_address)); 1737 } 1738 rel.r_offset += base_address; 1739 } 1740 } else if (sh->sh_type == SHT_RELA) { 1741 for (uint32_t j = 0; j < GetRelaNum(*sh); j++) { 1742 Elf_Rela& rela = GetRela(*sh, j); 1743 if (DEBUG_FIXUP) { 1744 LOG(INFO) << StringPrintf("In %s moving Elf_Rela[%d] from 0x%" PRIx64 " to 0x%" PRIx64, 1745 GetFile().GetPath().c_str(), j, 1746 static_cast<uint64_t>(rela.r_offset), 1747 static_cast<uint64_t>(rela.r_offset + base_address)); 1748 } 1749 rela.r_offset += base_address; 1750 } 1751 } 1752 } 1753 return true; 1754 } 1755 1756 // Explicit instantiations 1757 template class ElfFileImpl<ElfTypes32>; 1758 template class ElfFileImpl<ElfTypes64>; 1759 1760 ElfFile::ElfFile(ElfFileImpl32* elf32) : elf32_(elf32), elf64_(nullptr) { 1761 } 1762 1763 ElfFile::ElfFile(ElfFileImpl64* elf64) : elf32_(nullptr), elf64_(elf64) { 1764 } 1765 1766 ElfFile::~ElfFile() { 1767 // Should never have 32 and 64-bit impls. 1768 CHECK_NE(elf32_.get() == nullptr, elf64_.get() == nullptr); 1769 } 1770 1771 ElfFile* ElfFile::Open(File* file, bool writable, bool program_header_only, std::string* error_msg, 1772 uint8_t* requested_base) { 1773 if (file->GetLength() < EI_NIDENT) { 1774 *error_msg = StringPrintf("File %s is too short to be a valid ELF file", 1775 file->GetPath().c_str()); 1776 return nullptr; 1777 } 1778 std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT, PROT_READ, MAP_PRIVATE, file->Fd(), 0, 1779 file->GetPath().c_str(), error_msg)); 1780 if (map == nullptr && map->Size() != EI_NIDENT) { 1781 return nullptr; 1782 } 1783 uint8_t* header = map->Begin(); 1784 if (header[EI_CLASS] == ELFCLASS64) { 1785 ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, writable, program_header_only, 1786 error_msg, requested_base); 1787 if (elf_file_impl == nullptr) 1788 return nullptr; 1789 return new ElfFile(elf_file_impl); 1790 } else if (header[EI_CLASS] == ELFCLASS32) { 1791 ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, writable, program_header_only, 1792 error_msg, requested_base); 1793 if (elf_file_impl == nullptr) { 1794 return nullptr; 1795 } 1796 return new ElfFile(elf_file_impl); 1797 } else { 1798 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d", 1799 ELFCLASS32, ELFCLASS64, 1800 file->GetPath().c_str(), 1801 header[EI_CLASS]); 1802 return nullptr; 1803 } 1804 } 1805 1806 ElfFile* ElfFile::Open(File* file, int mmap_prot, int mmap_flags, std::string* error_msg) { 1807 if (file->GetLength() < EI_NIDENT) { 1808 *error_msg = StringPrintf("File %s is too short to be a valid ELF file", 1809 file->GetPath().c_str()); 1810 return nullptr; 1811 } 1812 std::unique_ptr<MemMap> map(MemMap::MapFile(EI_NIDENT, PROT_READ, MAP_PRIVATE, file->Fd(), 0, 1813 file->GetPath().c_str(), error_msg)); 1814 if (map == nullptr && map->Size() != EI_NIDENT) { 1815 return nullptr; 1816 } 1817 uint8_t* header = map->Begin(); 1818 if (header[EI_CLASS] == ELFCLASS64) { 1819 ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, mmap_prot, mmap_flags, error_msg); 1820 if (elf_file_impl == nullptr) { 1821 return nullptr; 1822 } 1823 return new ElfFile(elf_file_impl); 1824 } else if (header[EI_CLASS] == ELFCLASS32) { 1825 ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, mmap_prot, mmap_flags, error_msg); 1826 if (elf_file_impl == nullptr) { 1827 return nullptr; 1828 } 1829 return new ElfFile(elf_file_impl); 1830 } else { 1831 *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d", 1832 ELFCLASS32, ELFCLASS64, 1833 file->GetPath().c_str(), 1834 header[EI_CLASS]); 1835 return nullptr; 1836 } 1837 } 1838 1839 #define DELEGATE_TO_IMPL(func, ...) \ 1840 if (elf64_.get() != nullptr) { \ 1841 return elf64_->func(__VA_ARGS__); \ 1842 } else { \ 1843 DCHECK(elf32_.get() != nullptr); \ 1844 return elf32_->func(__VA_ARGS__); \ 1845 } 1846 1847 bool ElfFile::Load(bool executable, std::string* error_msg) { 1848 DELEGATE_TO_IMPL(Load, executable, error_msg); 1849 } 1850 1851 const uint8_t* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const { 1852 DELEGATE_TO_IMPL(FindDynamicSymbolAddress, symbol_name); 1853 } 1854 1855 size_t ElfFile::Size() const { 1856 DELEGATE_TO_IMPL(Size); 1857 } 1858 1859 uint8_t* ElfFile::Begin() const { 1860 DELEGATE_TO_IMPL(Begin); 1861 } 1862 1863 uint8_t* ElfFile::End() const { 1864 DELEGATE_TO_IMPL(End); 1865 } 1866 1867 const File& ElfFile::GetFile() const { 1868 DELEGATE_TO_IMPL(GetFile); 1869 } 1870 1871 bool ElfFile::GetSectionOffsetAndSize(const char* section_name, uint64_t* offset, uint64_t* size) { 1872 if (elf32_.get() == nullptr) { 1873 CHECK(elf64_.get() != nullptr); 1874 1875 Elf64_Shdr *shdr = elf64_->FindSectionByName(section_name); 1876 if (shdr == nullptr) { 1877 return false; 1878 } 1879 if (offset != nullptr) { 1880 *offset = shdr->sh_offset; 1881 } 1882 if (size != nullptr) { 1883 *size = shdr->sh_size; 1884 } 1885 return true; 1886 } else { 1887 Elf32_Shdr *shdr = elf32_->FindSectionByName(section_name); 1888 if (shdr == nullptr) { 1889 return false; 1890 } 1891 if (offset != nullptr) { 1892 *offset = shdr->sh_offset; 1893 } 1894 if (size != nullptr) { 1895 *size = shdr->sh_size; 1896 } 1897 return true; 1898 } 1899 } 1900 1901 uint64_t ElfFile::FindSymbolAddress(unsigned section_type, 1902 const std::string& symbol_name, 1903 bool build_map) { 1904 DELEGATE_TO_IMPL(FindSymbolAddress, section_type, symbol_name, build_map); 1905 } 1906 1907 bool ElfFile::GetLoadedSize(size_t* size, std::string* error_msg) const { 1908 DELEGATE_TO_IMPL(GetLoadedSize, size, error_msg); 1909 } 1910 1911 bool ElfFile::Strip(File* file, std::string* error_msg) { 1912 std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, error_msg)); 1913 if (elf_file.get() == nullptr) { 1914 return false; 1915 } 1916 1917 if (elf_file->elf64_.get() != nullptr) 1918 return elf_file->elf64_->Strip(error_msg); 1919 else 1920 return elf_file->elf32_->Strip(error_msg); 1921 } 1922 1923 bool ElfFile::Fixup(uint64_t base_address) { 1924 if (elf64_.get() != nullptr) { 1925 return elf64_->Fixup(static_cast<Elf64_Addr>(base_address)); 1926 } else { 1927 DCHECK(elf32_.get() != nullptr); 1928 CHECK(IsUint<32>(base_address)) << std::hex << base_address; 1929 return elf32_->Fixup(static_cast<Elf32_Addr>(base_address)); 1930 } 1931 DELEGATE_TO_IMPL(Fixup, base_address); 1932 } 1933 1934 } // namespace art 1935