diff options
| -rw-r--r-- | dex2oat/dex2oat_test.cc | 3 | ||||
| -rw-r--r-- | runtime/oat/elf_file.cc | 71 | ||||
| -rw-r--r-- | runtime/oat/elf_file.h | 58 | ||||
| -rw-r--r-- | runtime/oat/elf_file_impl.h | 49 |
4 files changed, 44 insertions, 137 deletions
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc index 97c467b600..da97a4effd 100644 --- a/dex2oat/dex2oat_test.cc +++ b/dex2oat/dex2oat_test.cc @@ -2038,8 +2038,7 @@ TEST_F(Dex2oatTest, LoadOutOfDateOatFile) { /*reservation=*/nullptr, &error_msg)) << error_msg; - const uint8_t* base_address = elf_file->Is64Bit() ? elf_file->GetImpl64()->GetBaseAddress() : - elf_file->GetImpl32()->GetBaseAddress(); + const uint8_t* base_address = elf_file->GetBaseAddress(); const uint8_t* oatdata = elf_file->FindDynamicSymbolAddress("oatdata"); ASSERT_TRUE(oatdata != nullptr); ASSERT_TRUE(oatdata > base_address); diff --git a/runtime/oat/elf_file.cc b/runtime/oat/elf_file.cc index 8bbad65c94..3bcecc5205 100644 --- a/runtime/oat/elf_file.cc +++ b/runtime/oat/elf_file.cc @@ -38,8 +38,6 @@ using android::base::StringPrintf; template <typename ElfTypes> ElfFileImpl<ElfTypes>::ElfFileImpl(File* file) : header_(nullptr), - base_address_(nullptr), - program_headers_start_(nullptr), section_headers_start_(nullptr), dynamic_program_header_(nullptr), dynamic_section_start_(nullptr), @@ -875,17 +873,6 @@ bool ElfFileImpl<ElfTypes>::ValidPointer(const uint8_t* start) const { template class ElfFileImpl<ElfTypes32>; template class ElfFileImpl<ElfTypes64>; -ElfFile::ElfFile(ElfFileImpl32* elf32) : elf32_(elf32), elf64_(nullptr) { -} - -ElfFile::ElfFile(ElfFileImpl64* elf64) : elf32_(nullptr), elf64_(elf64) { -} - -ElfFile::~ElfFile() { - // Should never have 32 and 64-bit impls. - CHECK_NE(elf32_.get() == nullptr, elf64_.get() == nullptr); -} - ElfFile* ElfFile::Open(File* file, bool low_4gb, /*out*/ std::string* error_msg) { @@ -907,17 +894,9 @@ ElfFile* ElfFile::Open(File* file, } uint8_t* header = map.Begin(); if (header[EI_CLASS] == ELFCLASS64) { - ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, low_4gb, error_msg); - if (elf_file_impl == nullptr) { - return nullptr; - } - return new ElfFile(elf_file_impl); + return ElfFileImpl64::Open(file, low_4gb, error_msg); } else if (header[EI_CLASS] == ELFCLASS32) { - ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, low_4gb, error_msg); - if (elf_file_impl == nullptr) { - return nullptr; - } - return new ElfFile(elf_file_impl); + return ElfFileImpl32::Open(file, low_4gb, error_msg); } else { *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d", ELFCLASS32, ELFCLASS64, @@ -927,50 +906,4 @@ ElfFile* ElfFile::Open(File* file, } } -#define DELEGATE_TO_IMPL(func, ...) \ - if (elf64_.get() != nullptr) { \ - return elf64_->func(__VA_ARGS__); \ - } else { \ - DCHECK(elf32_.get() != nullptr); \ - return elf32_->func(__VA_ARGS__); \ - } - -bool ElfFile::Load(File* file, - bool executable, - bool low_4gb, - /*inout*/MemMap* reservation, - /*out*/std::string* error_msg) { - DELEGATE_TO_IMPL(Load, file, executable, low_4gb, reservation, error_msg); -} - -const uint8_t* ElfFile::FindDynamicSymbolAddress(const std::string& symbol_name) const { - DELEGATE_TO_IMPL(FindDynamicSymbolAddress, symbol_name); -} - -size_t ElfFile::Size() const { - DELEGATE_TO_IMPL(Size); -} - -uint8_t* ElfFile::Begin() const { - DELEGATE_TO_IMPL(Begin); -} - -uint8_t* ElfFile::End() const { - DELEGATE_TO_IMPL(End); -} - -const std::string& ElfFile::GetFilePath() const { - DELEGATE_TO_IMPL(GetFilePath); -} - -bool ElfFile::GetLoadedSize(size_t* size, std::string* error_msg) const { - DELEGATE_TO_IMPL(GetLoadedSize, size, error_msg); -} - -size_t ElfFile::GetElfSegmentAlignmentFromFile() const { - DELEGATE_TO_IMPL(GetElfSegmentAlignmentFromFile); -} - -const uint8_t* ElfFile::GetBaseAddress() const { DELEGATE_TO_IMPL(GetBaseAddress); } - } // namespace art diff --git a/runtime/oat/elf_file.h b/runtime/oat/elf_file.h index 4206e1926a..fa49e86e55 100644 --- a/runtime/oat/elf_file.h +++ b/runtime/oat/elf_file.h @@ -17,17 +17,16 @@ #ifndef ART_RUNTIME_OAT_ELF_FILE_H_ #define ART_RUNTIME_OAT_ELF_FILE_H_ -#include <memory> #include <string> +#include <vector> #include "base/macros.h" +#include "base/mem_map.h" #include "base/os.h" #include "elf/elf_utils.h" namespace art HIDDEN { -class MemMap; - template <typename ElfTypes> class ElfFileImpl; @@ -44,46 +43,51 @@ class ElfFile { bool low_4gb, /*out*/ std::string* error_msg); - ~ElfFile(); + virtual ~ElfFile() = default; // Load segments into memory based on PT_LOAD program headers - bool Load(File* file, - bool executable, - bool low_4gb, - /*inout*/ MemMap* reservation, - /*out*/ std::string* error_msg); + virtual bool Load(File* file, + bool executable, + bool low_4gb, + /*inout*/ MemMap* reservation, + /*out*/ std::string* error_msg) = 0; - const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const; + virtual const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const = 0; - size_t Size() const; + const std::string& GetFilePath() const { return file_path_; } - // The start of the memory map address range for this ELF file. - uint8_t* Begin() const; + uint8_t* GetBaseAddress() const { return base_address_; } - // The end of the memory map address range for this ELF file. - uint8_t* End() const; + uint8_t* Begin() const { return map_.Begin(); } - const std::string& GetFilePath() const; + uint8_t* End() const { return map_.End(); } - bool GetLoadedSize(size_t* size, std::string* error_msg) const; + size_t Size() const { return map_.Size(); } - size_t GetElfSegmentAlignmentFromFile() const; + virtual bool GetLoadedSize(size_t* size, std::string* error_msg) const = 0; - const uint8_t* GetBaseAddress() const; + virtual size_t GetElfSegmentAlignmentFromFile() const = 0; - bool Is64Bit() const { return elf64_.get() != nullptr; } + virtual bool Is64Bit() const = 0; - ElfFileImpl32* GetImpl32() const { return elf32_.get(); } + protected: + ElfFile() = default; - ElfFileImpl64* GetImpl64() const { return elf64_.get(); } + const std::string file_path_; - private: - explicit ElfFile(ElfFileImpl32* elf32); - explicit ElfFile(ElfFileImpl64* elf64); + // ELF header mapping. If program_header_only_ is false, will + // actually point to the entire elf file. + MemMap map_; + std::vector<MemMap> segments_; - const std::unique_ptr<ElfFileImpl32> elf32_; - const std::unique_ptr<ElfFileImpl64> elf64_; + // Pointer to start of first PT_LOAD program segment after Load() + // when program_header_only_ is true. + uint8_t* base_address_ = nullptr; + // The program header should always available but use GetProgramHeadersStart() to be sure. + uint8_t* program_headers_start_ = nullptr; + + private: DISALLOW_COPY_AND_ASSIGN(ElfFile); }; diff --git a/runtime/oat/elf_file_impl.h b/runtime/oat/elf_file_impl.h index 0e8dc6ac89..b117c82d74 100644 --- a/runtime/oat/elf_file_impl.h +++ b/runtime/oat/elf_file_impl.h @@ -17,16 +17,18 @@ #ifndef ART_RUNTIME_OAT_ELF_FILE_IMPL_H_ #define ART_RUNTIME_OAT_ELF_FILE_IMPL_H_ +#include <type_traits> #include <vector> #include "base/macros.h" #include "base/mem_map.h" #include "base/os.h" +#include "elf_file.h" namespace art HIDDEN { template <typename ElfTypes> -class ElfFileImpl { +class ElfFileImpl : public ElfFile { public: using Elf_Addr = typename ElfTypes::Addr; using Elf_Off = typename ElfTypes::Off; @@ -45,26 +47,6 @@ class ElfFileImpl { bool low_4gb, /*out*/ std::string* error_msg); - const std::string& GetFilePath() const { - return file_path_; - } - - uint8_t* GetBaseAddress() const { - return base_address_; - } - - uint8_t* Begin() const { - return map_.Begin(); - } - - uint8_t* End() const { - return map_.End(); - } - - size_t Size() const { - return map_.Size(); - } - Elf_Ehdr& GetHeader() const; Elf_Word GetProgramHeaderNum() const; @@ -74,7 +56,7 @@ class ElfFileImpl { Elf_Shdr* FindSectionByType(Elf_Word type) const; // Find .dynsym using .hash for more efficient lookup than FindSymbolAddress. - const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const; + const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name) const override; static bool IsSymbolSectionType(Elf_Word section_type); Elf_Word GetSymbolNum(Elf_Shdr&) const; @@ -84,18 +66,20 @@ class ElfFileImpl { Elf_Dyn& GetDynamic(Elf_Word) const; // Retrieves the expected size when the file is loaded at runtime. Returns true if successful. - bool GetLoadedSize(size_t* size, std::string* error_msg) const; + bool GetLoadedSize(size_t* size, std::string* error_msg) const override; // Get the alignment of the first loadable program segment. Return 0 if no loadable segment found. - size_t GetElfSegmentAlignmentFromFile() const; + size_t GetElfSegmentAlignmentFromFile() const override; // Load segments into memory based on PT_LOAD program headers. // executable is true at run time, false at compile time. bool Load(File* file, bool executable, bool low_4gb, - /*inout*/MemMap* reservation, - /*out*/std::string* error_msg); + /*inout*/ MemMap* reservation, + /*out*/ std::string* error_msg) override; + + bool Is64Bit() const override { return std::is_same_v<ElfTypes, ElfTypes64>; } private: explicit ElfFileImpl(File* file); @@ -131,20 +115,7 @@ class ElfFileImpl { // Lookup a string by section type. Returns null for special 0 offset. const char* GetString(Elf_Word section_type, Elf_Word) const; - const std::string file_path_; - - // ELF header mapping. If program_header_only_ is false, will - // actually point to the entire elf file. - MemMap map_; Elf_Ehdr* header_; - std::vector<MemMap> segments_; - - // Pointer to start of first PT_LOAD program segment after Load() - // when program_header_only_ is true. - uint8_t* base_address_; - - // The program header should always available but use GetProgramHeadersStart() to be sure. - uint8_t* program_headers_start_; // Conditionally available values. Use accessors to ensure they exist if they are required. uint8_t* section_headers_start_; |