diff options
-rw-r--r-- | dex2oat/Android.bp | 1 | ||||
-rw-r--r-- | dex2oat/linker/elf_writer.cc | 52 | ||||
-rw-r--r-- | dex2oat/linker/elf_writer.h | 9 | ||||
-rw-r--r-- | runtime/oat/elf_file.cc | 237 | ||||
-rw-r--r-- | runtime/oat/elf_file.h | 11 | ||||
-rw-r--r-- | runtime/oat/elf_file_impl.h | 21 | ||||
-rw-r--r-- | runtime/oat/oat_file.cc | 27 |
7 files changed, 3 insertions, 355 deletions
diff --git a/dex2oat/Android.bp b/dex2oat/Android.bp index f85a11b532..186794e243 100644 --- a/dex2oat/Android.bp +++ b/dex2oat/Android.bp @@ -37,7 +37,6 @@ art_cc_defaults { "driver/compiler_driver.cc", "interpreter/interpreter_switch_impl1.cc", "linker/code_info_table_deduper.cc", - "linker/elf_writer.cc", "linker/elf_writer_quick.cc", "linker/image_writer.cc", "linker/multi_oat_relative_patcher.cc", diff --git a/dex2oat/linker/elf_writer.cc b/dex2oat/linker/elf_writer.cc deleted file mode 100644 index c050695e32..0000000000 --- a/dex2oat/linker/elf_writer.cc +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "elf_writer.h" - -#include "base/unix_file/fd_file.h" -#include "oat/elf_file.h" - -namespace art { -namespace linker { - -uintptr_t ElfWriter::GetOatDataAddress(ElfFile* elf_file) { - uintptr_t oatdata_address = elf_file->FindSymbolAddress(SHT_DYNSYM, - "oatdata", - false); - CHECK_NE(0U, oatdata_address); - return oatdata_address; -} - -void ElfWriter::GetOatElfInformation(File* file, - size_t* oat_loaded_size, - size_t* oat_data_offset) { - std::string error_msg; - std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, - false, - false, - /*low_4gb*/false, - &error_msg)); - CHECK(elf_file.get() != nullptr) << error_msg; - - bool success = elf_file->GetLoadedSize(oat_loaded_size, &error_msg); - CHECK(success) << error_msg; - CHECK_NE(0U, *oat_loaded_size); - *oat_data_offset = GetOatDataAddress(elf_file.get()); - CHECK_NE(0U, *oat_data_offset); -} - -} // namespace linker -} // namespace art diff --git a/dex2oat/linker/elf_writer.h b/dex2oat/linker/elf_writer.h index d27d4fa92c..b60be6c728 100644 --- a/dex2oat/linker/elf_writer.h +++ b/dex2oat/linker/elf_writer.h @@ -43,15 +43,6 @@ namespace linker { class ElfWriter { public: - // Looks up information about location of oat file in elf file container. - // Used for ImageWriter to perform memory layout. - static void GetOatElfInformation(File* file, - size_t* oat_loaded_size, - size_t* oat_data_offset); - - // Returns runtime oat_data runtime address for an opened ElfFile. - static uintptr_t GetOatDataAddress(ElfFile* elf_file); - virtual ~ElfWriter() {} virtual void Start() = 0; diff --git a/runtime/oat/elf_file.cc b/runtime/oat/elf_file.cc index 5fb8053856..76b8ed623c 100644 --- a/runtime/oat/elf_file.cc +++ b/runtime/oat/elf_file.cc @@ -80,20 +80,6 @@ ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(File* file, } template <typename ElfTypes> -ElfFileImpl<ElfTypes>* ElfFileImpl<ElfTypes>::Open(File* file, - int prot, - int flags, - bool low_4gb, - std::string* error_msg) { - std::unique_ptr<ElfFileImpl<ElfTypes>> elf_file( - new ElfFileImpl<ElfTypes>(file, (prot & PROT_WRITE) != 0, /* program_header_only= */ false)); - if (!elf_file->Setup(file, prot, flags, low_4gb, error_msg)) { - return nullptr; - } - return elf_file.release(); -} - -template <typename ElfTypes> bool ElfFileImpl<ElfTypes>::Setup(File* file, int prot, int flags, @@ -960,66 +946,6 @@ typename ElfTypes::Dyn& ElfFileImpl<ElfTypes>::GetDynamic(Elf_Word i) 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) { - return dyn; - } - } - return nullptr; -} - -template <typename ElfTypes> -typename ElfTypes::Word ElfFileImpl<ElfTypes>::FindDynamicValueByType(Elf_Sword type) const { - Elf_Dyn* dyn = FindDynamicByType(type); - if (dyn == nullptr) { - return 0; - } else { - return dyn->d_un.d_val; - } -} - -template <typename ElfTypes> -typename ElfTypes::Rel* ElfFileImpl<ElfTypes>::GetRelSectionStart(Elf_Shdr& section_header) const { - CHECK(SHT_REL == section_header.sh_type) << file_path_ << " " << section_header.sh_type; - return reinterpret_cast<Elf_Rel*>(Begin() + section_header.sh_offset); -} - -template <typename ElfTypes> -typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelNum(Elf_Shdr& section_header) const { - CHECK(SHT_REL == section_header.sh_type) << file_path_ << " " << section_header.sh_type; - CHECK_NE(0U, section_header.sh_entsize) << file_path_; - return section_header.sh_size / section_header.sh_entsize; -} - -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_path_ << " " << section_header.sh_type; - CHECK_LT(i, GetRelNum(section_header)) << file_path_; - return *(GetRelSectionStart(section_header) + i); -} - -template <typename ElfTypes> -typename ElfTypes::Rela* ElfFileImpl<ElfTypes>::GetRelaSectionStart(Elf_Shdr& section_header) const { - CHECK(SHT_RELA == section_header.sh_type) << file_path_ << " " << section_header.sh_type; - return reinterpret_cast<Elf_Rela*>(Begin() + section_header.sh_offset); -} - -template <typename ElfTypes> -typename ElfTypes::Word ElfFileImpl<ElfTypes>::GetRelaNum(Elf_Shdr& section_header) const { - CHECK(SHT_RELA == section_header.sh_type) << file_path_ << " " << section_header.sh_type; - return section_header.sh_size / section_header.sh_entsize; -} - -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_path_ << " " << section_header.sh_type; - CHECK_LT(i, GetRelaNum(section_header)) << file_path_; - return *(GetRelaSectionStart(section_header) + i); -} - -template <typename ElfTypes> bool ElfFileImpl<ElfTypes>::GetLoadedSize(size_t* size, std::string* error_msg) const { uint8_t* vaddr_begin; return GetLoadedAddressRange(&vaddr_begin, size, error_msg); @@ -1383,107 +1309,6 @@ typename ElfTypes::Shdr* ElfFileImpl<ElfTypes>::FindSectionByName( return nullptr; } -template <typename ElfTypes> -bool ElfFileImpl<ElfTypes>::Strip(File* file, std::string* error_msg) { - // ELF files produced by MCLinker look roughly like this - // - // +------------+ - // | Elf_Ehdr | contains number of Elf_Shdr and offset to first - // +------------+ - // | Elf_Phdr | program headers - // | Elf_Phdr | - // | ... | - // | Elf_Phdr | - // +------------+ - // | section | mixture of needed and unneeded sections - // +------------+ - // | section | - // +------------+ - // | ... | - // +------------+ - // | section | - // +------------+ - // | Elf_Shdr | section headers - // | Elf_Shdr | - // | ... | contains offset to section start - // | Elf_Shdr | - // +------------+ - // - // To strip: - // - leave the Elf_Ehdr and Elf_Phdr values in place. - // - walk the sections making a new set of Elf_Shdr section headers for what we want to keep - // - move the sections are keeping up to fill in gaps of sections we want to strip - // - write new Elf_Shdr section headers to end of file, updating Elf_Ehdr - // - truncate rest of file - // - - std::vector<Elf_Shdr> section_headers; - std::vector<Elf_Word> section_headers_original_indexes; - section_headers.reserve(GetSectionHeaderNum()); - - - Elf_Shdr* string_section = GetSectionNameStringSection(); - CHECK(string_section != nullptr); - for (Elf_Word i = 0; i < GetSectionHeaderNum(); i++) { - Elf_Shdr* sh = GetSectionHeader(i); - CHECK(sh != nullptr); - const char* name = GetString(*string_section, sh->sh_name); - if (name == nullptr) { - CHECK_EQ(0U, i); - section_headers.push_back(*sh); - section_headers_original_indexes.push_back(0); - continue; - } - std::string_view name_sv(name); - if (name_sv.starts_with(".debug") || (name_sv == ".strtab") || (name_sv == ".symtab")) { - continue; - } - section_headers.push_back(*sh); - section_headers_original_indexes.push_back(i); - } - CHECK_NE(0U, section_headers.size()); - CHECK_EQ(section_headers.size(), section_headers_original_indexes.size()); - - // section 0 is the null section, sections start at offset of first section - CHECK(GetSectionHeader(1) != nullptr); - Elf_Off offset = GetSectionHeader(1)->sh_offset; - for (size_t i = 1; i < section_headers.size(); i++) { - Elf_Shdr& new_sh = section_headers[i]; - Elf_Shdr* old_sh = GetSectionHeader(section_headers_original_indexes[i]); - CHECK(old_sh != nullptr); - CHECK_EQ(new_sh.sh_name, old_sh->sh_name); - if (old_sh->sh_addralign > 1) { - offset = RoundUp(offset, old_sh->sh_addralign); - } - if (old_sh->sh_offset == offset) { - // already in place - offset += old_sh->sh_size; - continue; - } - // shift section earlier - memmove(Begin() + offset, - Begin() + old_sh->sh_offset, - old_sh->sh_size); - new_sh.sh_offset = offset; - offset += old_sh->sh_size; - } - - Elf_Off shoff = offset; - size_t section_headers_size_in_bytes = section_headers.size() * sizeof(Elf_Shdr); - memcpy(Begin() + offset, §ion_headers[0], section_headers_size_in_bytes); - offset += section_headers_size_in_bytes; - - GetHeader().e_shnum = section_headers.size(); - GetHeader().e_shoff = shoff; - int result = ftruncate(file->Fd(), offset); - if (result != 0) { - *error_msg = StringPrintf("Failed to truncate while stripping ELF file: '%s': %s", - file->GetPath().c_str(), strerror(errno)); - return false; - } - return true; -} - // Explicit instantiations template class ElfFileImpl<ElfTypes32>; template class ElfFileImpl<ElfTypes64>; @@ -1550,55 +1375,6 @@ ElfFile* ElfFile::Open(File* file, } } -ElfFile* ElfFile::Open(File* file, int mmap_prot, int mmap_flags, /*out*/std::string* error_msg) { - // low_4gb support not required for this path. - constexpr bool low_4gb = false; - if (file->GetLength() < EI_NIDENT) { - *error_msg = StringPrintf("File %s is too short to be a valid ELF file", - file->GetPath().c_str()); - return nullptr; - } - MemMap map = MemMap::MapFile(EI_NIDENT, - PROT_READ, - MAP_PRIVATE, - file->Fd(), - /* start= */ 0, - low_4gb, - file->GetPath().c_str(), - error_msg); - if (!map.IsValid() || map.Size() != EI_NIDENT) { - return nullptr; - } - uint8_t* header = map.Begin(); - if (header[EI_CLASS] == ELFCLASS64) { - ElfFileImpl64* elf_file_impl = ElfFileImpl64::Open(file, - mmap_prot, - mmap_flags, - low_4gb, - error_msg); - if (elf_file_impl == nullptr) { - return nullptr; - } - return new ElfFile(elf_file_impl); - } else if (header[EI_CLASS] == ELFCLASS32) { - ElfFileImpl32* elf_file_impl = ElfFileImpl32::Open(file, - mmap_prot, - mmap_flags, - low_4gb, - error_msg); - if (elf_file_impl == nullptr) { - return nullptr; - } - return new ElfFile(elf_file_impl); - } else { - *error_msg = StringPrintf("Failed to find expected EI_CLASS value %d or %d in %s, found %d", - ELFCLASS32, ELFCLASS64, - file->GetPath().c_str(), - header[EI_CLASS]); - return nullptr; - } -} - #define DELEGATE_TO_IMPL(func, ...) \ if (elf64_.get() != nullptr) { \ return elf64_->func(__VA_ARGS__); \ @@ -1690,17 +1466,4 @@ size_t ElfFile::GetElfSegmentAlignmentFromFile() const { const uint8_t* ElfFile::GetBaseAddress() const { DELEGATE_TO_IMPL(GetBaseAddress); } -bool ElfFile::Strip(File* file, std::string* error_msg) { - std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, /*low_4gb=*/false, error_msg)); - if (elf_file.get() == nullptr) { - return false; - } - - if (elf_file->elf64_.get() != nullptr) { - return elf_file->elf64_->Strip(file, error_msg); - } else { - return elf_file->elf32_->Strip(file, error_msg); - } -} - } // namespace art diff --git a/runtime/oat/elf_file.h b/runtime/oat/elf_file.h index 90e6c61817..ccfe82e0c2 100644 --- a/runtime/oat/elf_file.h +++ b/runtime/oat/elf_file.h @@ -45,12 +45,7 @@ class ElfFile { bool program_header_only, bool low_4gb, /*out*/std::string* error_msg); - // Open with specific mmap flags, Always maps in the whole file, not just the - // program header sections. - static ElfFile* Open(File* file, - int mmap_prot, - int mmap_flags, - /*out*/std::string* error_msg); + ~ElfFile(); // Load segments into memory based on PT_LOAD program headers @@ -86,10 +81,6 @@ class ElfFile { const uint8_t* GetBaseAddress() const; - // Strip an ELF file of unneeded debugging information. - // Returns true on success, false on failure. - static bool Strip(File* file, std::string* error_msg); - bool Is64Bit() const { return elf64_.get() != nullptr; } diff --git a/runtime/oat/elf_file_impl.h b/runtime/oat/elf_file_impl.h index 67c60e906c..67e9558cd2 100644 --- a/runtime/oat/elf_file_impl.h +++ b/runtime/oat/elf_file_impl.h @@ -48,12 +48,8 @@ class ElfFileImpl { bool writable, bool program_header_only, bool low_4gb, - /*out*/std::string* error_msg); - static ElfFileImpl* Open(File* file, - int mmap_prot, - int mmap_flags, - bool low_4gb, - /*out*/std::string* error_msg); + /*out*/ std::string* error_msg); + ~ElfFileImpl(); const std::string& GetFilePath() const { @@ -107,12 +103,6 @@ class ElfFileImpl { Elf_Word GetDynamicNum() const; Elf_Dyn& GetDynamic(Elf_Word) const; - Elf_Word GetRelNum(Elf_Shdr&) const; - Elf_Rel& GetRel(Elf_Shdr&, Elf_Word) const; - - Elf_Word GetRelaNum(Elf_Shdr&) const; - Elf_Rela& GetRela(Elf_Shdr&, 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; @@ -127,8 +117,6 @@ class ElfFileImpl { /*inout*/MemMap* reservation, /*out*/std::string* error_msg); - bool Strip(File* file, std::string* error_msg); - private: ElfFileImpl(File* file, bool writable, bool program_header_only); @@ -146,8 +134,6 @@ class ElfFileImpl { Elf_Dyn* GetDynamicSectionStart() const; Elf_Sym* GetSymbolSectionStart(Elf_Word section_type) const; const char* GetStringSectionStart(Elf_Word section_type) const; - Elf_Rel* GetRelSectionStart(Elf_Shdr&) const; - Elf_Rela* GetRelaSectionStart(Elf_Shdr&) const; Elf_Word* GetHashSectionStart() const; Elf_Word GetHashBucketNum() const; Elf_Word GetHashChainNum() const; @@ -184,9 +170,6 @@ class ElfFileImpl { Elf_Phdr* FindProgamHeaderByType(Elf_Word type) const; - Elf_Dyn* FindDynamicByType(Elf_Sword type) const; - Elf_Word FindDynamicValueByType(Elf_Sword type) const; - // Lookup a string by section type. Returns null for special 0 offset. const char* GetString(Elf_Word section_type, Elf_Word) const; diff --git a/runtime/oat/oat_file.cc b/runtime/oat/oat_file.cc index d6dd13410e..063b0b55ad 100644 --- a/runtime/oat/oat_file.cc +++ b/runtime/oat/oat_file.cc @@ -1622,12 +1622,6 @@ class ElfOatFile final : public OatFileBase { public: ElfOatFile(const std::string& filename, bool executable) : OatFileBase(filename, executable) {} - bool InitializeFromElfFile(int zip_fd, - ElfFile* elf_file, - VdexFile* vdex_file, - ArrayRef<const std::string> dex_filenames, - std::string* error_msg); - protected: const uint8_t* FindDynamicSymbolAddress(const std::string& symbol_name, std::string* error_msg) const override { @@ -1676,27 +1670,6 @@ class ElfOatFile final : public OatFileBase { DISALLOW_COPY_AND_ASSIGN(ElfOatFile); }; -bool ElfOatFile::InitializeFromElfFile(int zip_fd, - ElfFile* elf_file, - VdexFile* vdex_file, - ArrayRef<const std::string> dex_filenames, - std::string* error_msg) { - ScopedTrace trace(__PRETTY_FUNCTION__); - if (IsExecutable()) { - *error_msg = "Cannot initialize from elf file in executable mode."; - return false; - } - elf_file_.reset(elf_file); - SetVdex(vdex_file); - uint64_t offset, size; - bool has_section = elf_file->GetSectionOffsetAndSize(".rodata", &offset, &size); - CHECK(has_section); - SetBegin(elf_file->Begin() + offset); - SetEnd(elf_file->Begin() + size + offset); - // Ignore the optional .bss section when opening non-executable. - return Setup(zip_fd, dex_filenames, /*dex_files=*/{}, error_msg); -} - bool ElfOatFile::Load(const std::string& elf_filename, bool writable, bool executable, |