summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/dex2oat_test.cc3
-rw-r--r--runtime/oat/elf_file.cc71
-rw-r--r--runtime/oat/elf_file.h58
-rw-r--r--runtime/oat/elf_file_impl.h49
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_;