summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dex2oat/Android.bp1
-rw-r--r--dex2oat/linker/elf_writer.cc52
-rw-r--r--dex2oat/linker/elf_writer.h9
-rw-r--r--runtime/oat/elf_file.cc237
-rw-r--r--runtime/oat/elf_file.h11
-rw-r--r--runtime/oat/elf_file_impl.h21
-rw-r--r--runtime/oat/oat_file.cc27
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, &section_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,