diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/elf.h | 32 | ||||
-rw-r--r-- | runtime/elf_file.cc | 575 | ||||
-rw-r--r-- | runtime/elf_file.h | 10 | ||||
-rw-r--r-- | runtime/elf_file_impl.h | 21 |
4 files changed, 209 insertions, 429 deletions
diff --git a/runtime/elf.h b/runtime/elf.h index 60b5248..4514bb2 100644 --- a/runtime/elf.h +++ b/runtime/elf.h @@ -1852,6 +1852,38 @@ enum { VER_NEED_CURRENT = 1 }; +struct ElfTypes32 { + typedef Elf32_Addr Addr; + typedef Elf32_Off Off; + typedef Elf32_Half Half; + typedef Elf32_Word Word; + typedef Elf32_Sword Sword; + typedef Elf32_Ehdr Ehdr; + typedef Elf32_Shdr Shdr; + typedef Elf32_Sym Sym; + typedef Elf32_Rel Rel; + typedef Elf32_Rela Rela; + typedef Elf32_Phdr Phdr; + typedef Elf32_Dyn Dyn; +}; + +struct ElfTypes64 { + typedef Elf64_Addr Addr; + typedef Elf64_Off Off; + typedef Elf64_Half Half; + typedef Elf64_Word Word; + typedef Elf64_Sword Sword; + typedef Elf64_Xword Xword; + typedef Elf64_Sxword Sxword; + typedef Elf64_Ehdr Ehdr; + typedef Elf64_Shdr Shdr; + typedef Elf64_Sym Sym; + typedef Elf64_Rel Rel; + typedef Elf64_Rela Rela; + typedef Elf64_Phdr Phdr; + typedef Elf64_Dyn Dyn; +}; + // BEGIN android-changed #endif // ART_RUNTIME_ELF_H_ // END android-changed diff --git a/runtime/elf_file.cc b/runtime/elf_file.cc index 37e391d..8969e29 100644 --- a/runtime/elf_file.cc +++ b/runtime/elf_file.cc @@ -110,12 +110,10 @@ static void UnregisterCodeEntry(JITCodeEntry* entry) { delete entry; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::ElfFileImpl(File* file, bool writable, bool program_header_only, uint8_t* requested_base) +template <typename ElfTypes> +ElfFileImpl<ElfTypes>::ElfFileImpl(File* file, bool writable, + bool program_header_only, + uint8_t* requested_base) : file_(file), writable_(writable), program_header_only_(program_header_only), @@ -138,20 +136,12 @@ ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, CHECK(file != nullptr); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>* - ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Open(File* file, bool writable, bool program_header_only, - std::string* error_msg, uint8_t* requested_base) { - std::unique_ptr<ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>> - elf_file(new ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - (file, writable, program_header_only, requested_base)); +template <typename ElfTypes> +ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open( + File* file, bool writable, bool program_header_only, + std::string* error_msg, uint8_t* requested_base) { + std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes> + (file, writable, program_header_only, requested_base)); int prot; int flags; if (writable) { @@ -167,32 +157,20 @@ ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return elf_file.release(); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>* - ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Open(File* file, int prot, int flags, std::string* error_msg) { - std::unique_ptr<ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>> - elf_file(new ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - (file, (prot & PROT_WRITE) == PROT_WRITE, /*program_header_only*/false, - /*requested_base*/nullptr)); +template <typename ElfTypes> +ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open( + File* file, int prot, int flags, std::string* error_msg) { + std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file(new ElfFileImpl<ElfTypes> + (file, (prot & PROT_WRITE) == PROT_WRITE, /*program_header_only*/false, + /*requested_base*/nullptr)); if (!elf_file->Setup(prot, flags, error_msg)) { return nullptr; } return elf_file.release(); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Setup(int prot, int flags, std::string* error_msg) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::Setup(int prot, int flags, std::string* error_msg) { int64_t temp_file_length = file_->GetLength(); if (temp_file_length < 0) { errno = -temp_file_length; @@ -349,12 +327,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::~ElfFileImpl() { +template <typename ElfTypes> +ElfFileImpl<ElfTypes>::~ElfFileImpl() { STLDeleteElements(&segments_); delete symtab_symbol_table_; delete dynsym_symbol_table_; @@ -364,13 +338,9 @@ ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::CheckAndSet(Elf32_Off offset, const char* label, - uint8_t** target, std::string* error_msg) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::CheckAndSet(Elf32_Off offset, const char* label, + uint8_t** target, std::string* error_msg) { if (Begin() + offset >= End()) { *error_msg = StringPrintf("Offset %d is out of range for %s in ELF file: '%s'", offset, label, file_->GetPath().c_str()); @@ -380,12 +350,9 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::CheckSectionsLinked(const uint8_t* source, const uint8_t* target) const { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::CheckSectionsLinked(const uint8_t* source, + const uint8_t* target) const { // Only works in whole-program mode, as we need to iterate over the sections. // Note that we normally can't search by type, as duplicates are allowed for most section types. if (program_header_only_) { @@ -416,12 +383,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return target_found && source_section != nullptr && source_section->sh_link == target_index; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::CheckSectionsExist(std::string* error_msg) const { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::CheckSectionsExist(std::string* error_msg) const { if (!program_header_only_) { // If in full mode, need section headers. if (section_headers_start_ == nullptr) { @@ -504,12 +467,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::SetMap(MemMap* map, std::string* error_msg) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::SetMap(MemMap* map, std::string* error_msg) { if (map == nullptr) { // MemMap::Open should have already set an error. DCHECK(!error_msg->empty()); @@ -643,64 +602,41 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Ehdr& ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHeader() const { +template <typename ElfTypes> +typename ElfTypes::Ehdr& ElfFileImpl<ElfTypes>::GetHeader() const { CHECK(header_ != nullptr); // Header has been checked in SetMap. This is a sanity check. return *header_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -uint8_t* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetProgramHeadersStart() const { +template <typename ElfTypes> +uint8_t* ElfFileImpl<ElfTypes>::GetProgramHeadersStart() const { CHECK(program_headers_start_ != nullptr); // Header has been set in Setup. This is a sanity // check. return program_headers_start_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -uint8_t* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSectionHeadersStart() const { +template <typename ElfTypes> +uint8_t* ElfFileImpl<ElfTypes>::GetSectionHeadersStart() const { CHECK(!program_header_only_); // Only used in "full" mode. CHECK(section_headers_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. return section_headers_start_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Phdr& ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetDynamicProgramHeader() const { +template <typename ElfTypes> +typename ElfTypes::Phdr& ElfFileImpl<ElfTypes>::GetDynamicProgramHeader() const { CHECK(dynamic_program_header_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. return *dynamic_program_header_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Dyn* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetDynamicSectionStart() const { +template <typename ElfTypes> +typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::GetDynamicSectionStart() const { CHECK(dynamic_section_start_ != nullptr); // Is checked in CheckSectionsExist. Sanity check. return dynamic_section_start_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSymbolSectionStart(Elf_Word section_type) const { +template <typename ElfTypes> +typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbolSectionStart( + Elf_Word section_type) const { CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; switch (section_type) { case SHT_SYMTAB: { @@ -718,12 +654,9 @@ Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetStringSectionStart(Elf_Word section_type) const { +template <typename ElfTypes> +const char* ElfFileImpl<ElfTypes>::GetStringSectionStart( + Elf_Word section_type) const { CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; switch (section_type) { case SHT_SYMTAB: { @@ -739,12 +672,9 @@ const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetString(Elf_Word section_type, Elf_Word i) const { +template <typename ElfTypes> +const char* ElfFileImpl<ElfTypes>::GetString(Elf_Word section_type, + Elf_Word i) const { CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; if (i == 0) { return nullptr; @@ -759,39 +689,23 @@ const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, // WARNING: The following methods do not check for an error condition (non-existent hash section). // It is the caller's job to do this. -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHashSectionStart() const { +template <typename ElfTypes> +typename ElfTypes::Word* ElfFileImpl<ElfTypes>::GetHashSectionStart() const { return hash_section_start_; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHashBucketNum() const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucketNum() const { return GetHashSectionStart()[0]; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHashChainNum() const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChainNum() const { return GetHashSectionStart()[1]; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHashBucket(size_t i, bool* ok) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashBucket(size_t i, bool* ok) const { if (i >= GetHashBucketNum()) { *ok = false; return 0; @@ -801,12 +715,8 @@ Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return GetHashSectionStart()[2 + i]; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetHashChain(size_t i, bool* ok) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetHashChain(size_t i, bool* ok) const { if (i >= GetHashChainNum()) { *ok = false; return 0; @@ -816,21 +726,13 @@ Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return GetHashSectionStart()[2 + GetHashBucketNum() + i]; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetProgramHeaderNum() const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetProgramHeaderNum() const { return GetHeader().e_phnum; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Phdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetProgramHeader(Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::GetProgramHeader(Elf_Word i) const { CHECK_LT(i, GetProgramHeaderNum()) << file_->GetPath(); // Sanity check for caller. uint8_t* program_header = GetProgramHeadersStart() + (i * GetHeader().e_phentsize); if (program_header >= End()) { @@ -839,12 +741,8 @@ Elf_Phdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return reinterpret_cast<Elf_Phdr*>(program_header); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Phdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindProgamHeaderByType(Elf_Word type) const { +template <typename ElfTypes> +typename ElfTypes::Phdr* ElfFileImpl<ElfTypes>::FindProgamHeaderByType(Elf_Word type) const { for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { Elf_Phdr* program_header = GetProgramHeader(i); if (program_header->p_type == type) { @@ -854,21 +752,13 @@ Elf_Phdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return nullptr; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSectionHeaderNum() const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSectionHeaderNum() const { return GetHeader().e_shnum; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSectionHeader(Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionHeader(Elf_Word i) const { // Can only access arbitrary sections when we have the whole file, not just program header. // Even if we Load(), it doesn't bring in all the sections. CHECK(!program_header_only_) << file_->GetPath(); @@ -882,12 +772,8 @@ Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return reinterpret_cast<Elf_Shdr*>(section_header); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindSectionByType(Elf_Word type) const { +template <typename ElfTypes> +typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByType(Elf_Word type) const { // Can only access arbitrary sections when we have the whole file, not just program header. // We could change this to switch on known types if they were detected during loading. CHECK(!program_header_only_) << file_->GetPath(); @@ -914,21 +800,14 @@ static unsigned elfhash(const char *_name) { return h; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSectionNameStringSection() const { +template <typename ElfTypes> +typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::GetSectionNameStringSection() const { return GetSectionHeader(GetHeader().e_shstrndx); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -const uint8_t* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindDynamicSymbolAddress(const std::string& symbol_name) const { +template <typename ElfTypes> +const uint8_t* ElfFileImpl<ElfTypes>::FindDynamicSymbolAddress( + const std::string& symbol_name) const { // Check that we have a hash section. if (GetHashSectionStart() == nullptr) { return nullptr; // Failure condition. @@ -944,12 +823,9 @@ const uint8_t* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } // WARNING: Only called from FindDynamicSymbolAddress. Elides check for hash section. -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -const Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindDynamicSymbol(const std::string& symbol_name) const { +template <typename ElfTypes> +const typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindDynamicSymbol( + const std::string& symbol_name) const { if (GetHashBucketNum() == 0) { // No dynamic symbols at all. return nullptr; @@ -978,34 +854,21 @@ const Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return nullptr; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::IsSymbolSectionType(Elf_Word section_type) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::IsSymbolSectionType(Elf_Word section_type) { return ((section_type == SHT_SYMTAB) || (section_type == SHT_DYNSYM)); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSymbolNum(Elf_Shdr& section_header) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetSymbolNum(Elf_Shdr& section_header) const { CHECK(IsSymbolSectionType(section_header.sh_type)) << file_->GetPath() << " " << section_header.sh_type; CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath(); return section_header.sh_size / section_header.sh_entsize; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSymbol(Elf_Word section_type, - Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::GetSymbol(Elf_Word section_type, Elf_Word i) const { Elf_Sym* sym_start = GetSymbolSectionStart(section_type); if (sym_start == nullptr) { return nullptr; @@ -1013,14 +876,9 @@ Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return sym_start + i; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -typename ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::SymbolTable** ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetSymbolTable(Elf_Word section_type) { +template <typename ElfTypes> +typename ElfFileImpl<ElfTypes>::SymbolTable** +ElfFileImpl<ElfTypes>::GetSymbolTable(Elf_Word section_type) { CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; switch (section_type) { case SHT_SYMTAB: { @@ -1036,14 +894,9 @@ typename ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindSymbolByName(Elf_Word section_type, - const std::string& symbol_name, - bool build_map) { +template <typename ElfTypes> +typename ElfTypes::Sym* ElfFileImpl<ElfTypes>::FindSymbolByName( + Elf_Word section_type, const std::string& symbol_name, bool build_map) { CHECK(!program_header_only_) << file_->GetPath(); CHECK(IsSymbolSectionType(section_type)) << file_->GetPath() << " " << section_type; @@ -1122,14 +975,9 @@ Elf_Sym* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return nullptr; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Addr ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindSymbolAddress(Elf_Word section_type, - const std::string& symbol_name, - bool build_map) { +template <typename ElfTypes> +typename ElfTypes::Addr ElfFileImpl<ElfTypes>::FindSymbolAddress( + Elf_Word section_type, const std::string& symbol_name, bool build_map) { Elf_Sym* symbol = FindSymbolByName(section_type, symbol_name, build_map); if (symbol == nullptr) { return 0; @@ -1137,12 +985,9 @@ Elf_Addr ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return symbol->st_value; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetString(Elf_Shdr& string_section, Elf_Word i) const { +template <typename ElfTypes> +const char* ElfFileImpl<ElfTypes>::GetString(Elf_Shdr& string_section, + Elf_Word i) const { CHECK(!program_header_only_) << file_->GetPath(); // TODO: remove this static_cast from enum when using -std=gnu++0x if (static_cast<Elf_Word>(SHT_STRTAB) != string_section.sh_type) { @@ -1162,31 +1007,19 @@ const char* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return reinterpret_cast<const char*>(string); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetDynamicNum() const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetDynamicNum() const { return GetDynamicProgramHeader().p_filesz / sizeof(Elf_Dyn); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Dyn& ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetDynamic(Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Dyn& ElfFileImpl<ElfTypes>::GetDynamic(Elf_Word i) const { CHECK_LT(i, GetDynamicNum()) << file_->GetPath(); return *(GetDynamicSectionStart() + i); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Dyn* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindDynamicByType(Elf_Sword type) const { +template <typename ElfTypes> +typename ElfTypes::Dyn* ElfFileImpl<ElfTypes>::FindDynamicByType(Elf_Sword type) const { for (Elf_Word i = 0; i < GetDynamicNum(); i++) { Elf_Dyn* dyn = &GetDynamic(i); if (dyn->d_tag == type) { @@ -1196,12 +1029,8 @@ Elf_Dyn* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return NULL; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindDynamicValueByType(Elf_Sword type) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::FindDynamicValueByType(Elf_Sword type) const { Elf_Dyn* dyn = FindDynamicByType(type); if (dyn == NULL) { return 0; @@ -1210,76 +1039,48 @@ Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Rel* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRelSectionStart(Elf_Shdr& section_header) const { +template <typename ElfTypes> +typename ElfTypes::Rel* ElfFileImpl<ElfTypes>::GetRelSectionStart(Elf_Shdr& section_header) const { CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; return reinterpret_cast<Elf_Rel*>(Begin() + section_header.sh_offset); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRelNum(Elf_Shdr& section_header) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelNum(Elf_Shdr& section_header) const { CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; CHECK_NE(0U, section_header.sh_entsize) << file_->GetPath(); return section_header.sh_size / section_header.sh_entsize; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Rel& ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRel(Elf_Shdr& section_header, Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Rel& ElfFileImpl<ElfTypes>::GetRel(Elf_Shdr& section_header, Elf_Word i) const { CHECK(SHT_REL == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; CHECK_LT(i, GetRelNum(section_header)) << file_->GetPath(); return *(GetRelSectionStart(section_header) + i); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Rela* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRelaSectionStart(Elf_Shdr& section_header) const { +template <typename ElfTypes> +typename ElfTypes::Rela* ElfFileImpl<ElfTypes>::GetRelaSectionStart(Elf_Shdr& section_header) const { CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; return reinterpret_cast<Elf_Rela*>(Begin() + section_header.sh_offset); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Word ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRelaNum(Elf_Shdr& section_header) const { +template <typename ElfTypes> +typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelaNum(Elf_Shdr& section_header) const { CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; return section_header.sh_size / section_header.sh_entsize; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Rela& ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetRela(Elf_Shdr& section_header, Elf_Word i) const { +template <typename ElfTypes> +typename ElfTypes::Rela& ElfFileImpl<ElfTypes>::GetRela(Elf_Shdr& section_header, Elf_Word i) const { CHECK(SHT_RELA == section_header.sh_type) << file_->GetPath() << " " << section_header.sh_type; CHECK_LT(i, GetRelaNum(section_header)) << file_->GetPath(); return *(GetRelaSectionStart(section_header) + i); } // Base on bionic phdr_table_get_load_size -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -size_t ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GetLoadedSize() const { +template <typename ElfTypes> +size_t ElfFileImpl<ElfTypes>::GetLoadedSize() const { Elf_Addr min_vaddr = 0xFFFFFFFFu; Elf_Addr max_vaddr = 0x00000000u; for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { @@ -1303,12 +1104,8 @@ size_t ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return loaded_size; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Load(bool executable, std::string* error_msg) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::Load(bool executable, std::string* error_msg) { CHECK(program_header_only_) << file_->GetPath(); if (executable) { @@ -1543,12 +1340,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::ValidPointer(const uint8_t* start) const { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::ValidPointer(const uint8_t* start) const { for (size_t i = 0; i < segments_.size(); ++i) { const MemMap* segment = segments_[i]; if (segment->Begin() <= start && start < segment->End()) { @@ -1559,12 +1352,9 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FindSectionByName(const std::string& name) const { +template <typename ElfTypes> +typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName( + const std::string& name) const { CHECK(!program_header_only_); Elf_Shdr* shstrtab_sec = GetSectionNameStringSection(); if (shstrtab_sec == nullptr) { @@ -1586,12 +1376,8 @@ Elf_Shdr* ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return nullptr; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupDebugSections(typename std::make_signed<Elf_Off>::type base_address_delta) { const Elf_Shdr* debug_info = FindSectionByName(".debug_info"); const Elf_Shdr* debug_abbrev = FindSectionByName(".debug_abbrev"); const Elf_Shdr* debug_str = FindSectionByName(".debug_str"); @@ -1615,13 +1401,10 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::ApplyOatPatchesTo(const char* target_section_name, - typename std::make_signed<Elf_Off>::type delta) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::ApplyOatPatchesTo( + const char* target_section_name, + typename std::make_signed<Elf_Off>::type delta) { auto patches_section = FindSectionByName(".oat_patches"); if (patches_section == nullptr) { LOG(ERROR) << ".oat_patches section not found."; @@ -1648,15 +1431,12 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } // Apply .oat_patches to given section. -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::ApplyOatPatches(const uint8_t* patches, const uint8_t* patches_end, - const char* target_section_name, - typename std::make_signed<Elf_Off>::type delta, - uint8_t* to_patch, const uint8_t* to_patch_end) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::ApplyOatPatches( + const uint8_t* patches, const uint8_t* patches_end, + const char* target_section_name, + typename std::make_signed<Elf_Off>::type delta, + uint8_t* to_patch, const uint8_t* to_patch_end) { // Read null-terminated section name. const char* section_name; while ((section_name = reinterpret_cast<const char*>(patches))[0] != '\0') { @@ -1681,12 +1461,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return false; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -void ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::GdbJITSupport() { +template <typename ElfTypes> +void ElfFileImpl<ElfTypes>::GdbJITSupport() { // We only get here if we only are mapping the program header. DCHECK(program_header_only_); @@ -1694,15 +1470,12 @@ void ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, std::string error_msg; // Make it MAP_PRIVATE so we can just give it to gdb if all the necessary // sections are there. - std::unique_ptr<ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>> - all_ptr(Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE, - MAP_PRIVATE, &error_msg)); + std::unique_ptr<ElfFileImpl<ElfTypes>> all_ptr( + Open(const_cast<File*>(file_), PROT_READ | PROT_WRITE, MAP_PRIVATE, &error_msg)); if (all_ptr.get() == nullptr) { return; } - ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off>& all = *all_ptr; + ElfFileImpl<ElfTypes>& all = *all_ptr; // We need the eh_frame for gdb but debug info might be present without it. const Elf_Shdr* eh_frame = all.FindSectionByName(".eh_frame"); @@ -1732,12 +1505,8 @@ void ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, gdb_file_mapping_.reset(all_ptr.release()); } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Strip(std::string* error_msg) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::Strip(std::string* error_msg) { // ELF files produced by MCLinker look roughly like this // // +------------+ @@ -1840,12 +1609,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, static const bool DEBUG_FIXUP = false; -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::Fixup(Elf_Addr base_address) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::Fixup(Elf_Addr base_address) { if (!FixupDynamic(base_address)) { LOG(WARNING) << "Failed to fixup .dynamic in " << file_->GetPath(); return false; @@ -1878,12 +1643,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupDynamic(Elf_Addr base_address) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupDynamic(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetDynamicNum(); i++) { Elf_Dyn& elf_dyn = GetDynamic(i); Elf_Word d_tag = elf_dyn.d_tag; @@ -1902,12 +1663,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupSectionHeaders(Elf_Addr base_address) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupSectionHeaders(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { Elf_Shdr* sh = GetSectionHeader(i); CHECK(sh != nullptr); @@ -1926,12 +1683,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupProgramHeaders(Elf_Addr base_address) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupProgramHeaders(Elf_Addr base_address) { // TODO: ELFObjectFile doesn't have give to Elf_Phdr, so we do that ourselves for now. for (Elf_Word i = 0; i < GetProgramHeaderNum(); i++) { Elf_Phdr* ph = GetProgramHeader(i); @@ -1953,12 +1706,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupSymbols(Elf_Addr base_address, bool dynamic) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupSymbols(Elf_Addr base_address, bool dynamic) { Elf_Word section_type = dynamic ? SHT_DYNSYM : SHT_SYMTAB; // TODO: Unfortunate ELFObjectFile has protected symbol access, so use ElfFile Elf_Shdr* symbol_section = FindSectionByType(section_type); @@ -1983,12 +1732,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, return true; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> -bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, Elf_Rela, Elf_Dyn, Elf_Off> - ::FixupRelocations(Elf_Addr base_address) { +template <typename ElfTypes> +bool ElfFileImpl<ElfTypes>::FixupRelocations(Elf_Addr base_address) { for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { Elf_Shdr* sh = GetSectionHeader(i); CHECK(sh != nullptr); @@ -2020,10 +1765,8 @@ bool ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, } // Explicit instantiations -template class ElfFileImpl<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Word, - Elf32_Sword, Elf32_Addr, Elf32_Sym, Elf32_Rel, Elf32_Rela, Elf32_Dyn, Elf32_Off>; -template class ElfFileImpl<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Word, - Elf64_Sword, Elf64_Addr, Elf64_Sym, Elf64_Rel, Elf64_Rela, Elf64_Dyn, Elf64_Off>; +template class ElfFileImpl<ElfTypes32>; +template class ElfFileImpl<ElfTypes64>; ElfFile::ElfFile(ElfFileImpl32* elf32) : elf32_(elf32), elf64_(nullptr) { } diff --git a/runtime/elf_file.h b/runtime/elf_file.h index 286c2a6..fe6896d 100644 --- a/runtime/elf_file.h +++ b/runtime/elf_file.h @@ -26,16 +26,12 @@ #include "os.h" namespace art { -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> +template <typename ElfTypes> class ElfFileImpl; // Explicitly instantiated in elf_file.cc -typedef ElfFileImpl<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Word, Elf32_Sword, - Elf32_Addr, Elf32_Sym, Elf32_Rel, Elf32_Rela, Elf32_Dyn, Elf32_Off> ElfFileImpl32; -typedef ElfFileImpl<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Word, Elf64_Sword, - Elf64_Addr, Elf64_Sym, Elf64_Rel, Elf64_Rela, Elf64_Dyn, Elf64_Off> ElfFileImpl64; +typedef ElfFileImpl<ElfTypes32> ElfFileImpl32; +typedef ElfFileImpl<ElfTypes64> ElfFileImpl64; // Used for compile time and runtime for ElfFile access. Because of // the need for use at runtime, cannot directly use LLVM classes such as diff --git a/runtime/elf_file_impl.h b/runtime/elf_file_impl.h index 383dc41..047849a 100644 --- a/runtime/elf_file_impl.h +++ b/runtime/elf_file_impl.h @@ -32,11 +32,22 @@ extern "C" { struct JITCodeEntry; } -template <typename Elf_Ehdr, typename Elf_Phdr, typename Elf_Shdr, typename Elf_Word, - typename Elf_Sword, typename Elf_Addr, typename Elf_Sym, typename Elf_Rel, - typename Elf_Rela, typename Elf_Dyn, typename Elf_Off> +template <typename ElfTypes> class ElfFileImpl { public: + using Elf_Addr = typename ElfTypes::Addr; + using Elf_Off = typename ElfTypes::Off; + using Elf_Half = typename ElfTypes::Half; + using Elf_Word = typename ElfTypes::Word; + using Elf_Sword = typename ElfTypes::Sword; + using Elf_Ehdr = typename ElfTypes::Ehdr; + using Elf_Shdr = typename ElfTypes::Shdr; + using Elf_Sym = typename ElfTypes::Sym; + using Elf_Rel = typename ElfTypes::Rel; + using Elf_Rela = typename ElfTypes::Rela; + using Elf_Phdr = typename ElfTypes::Phdr; + using Elf_Dyn = typename ElfTypes::Dyn; + static ElfFileImpl* Open(File* file, bool writable, bool program_header_only, std::string* error_msg, uint8_t* requested_base = nullptr); static ElfFileImpl* Open(File* file, int mmap_prot, int mmap_flags, std::string* error_msg); @@ -209,9 +220,7 @@ class ElfFileImpl { // Support for GDB JIT uint8_t* jit_elf_image_; JITCodeEntry* jit_gdb_entry_; - std::unique_ptr<ElfFileImpl<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Word, - Elf_Sword, Elf_Addr, Elf_Sym, Elf_Rel, - Elf_Rela, Elf_Dyn, Elf_Off>> gdb_file_mapping_; + std::unique_ptr<ElfFileImpl<ElfTypes>> gdb_file_mapping_; void GdbJITSupport(); // Override the 'base' p_vaddr in the first LOAD segment with this value (if non-null). |