diff options
Diffstat (limited to 'compiler/elf_stripper.cc')
| -rw-r--r-- | compiler/elf_stripper.cc | 138 |
1 files changed, 0 insertions, 138 deletions
diff --git a/compiler/elf_stripper.cc b/compiler/elf_stripper.cc deleted file mode 100644 index 457d8a0940..0000000000 --- a/compiler/elf_stripper.cc +++ /dev/null @@ -1,138 +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_stripper.h" - -#include <unistd.h> -#include <sys/types.h> -#include <memory> -#include <vector> - -#include "base/logging.h" -#include "base/stringprintf.h" -#include "elf_file.h" -#include "elf_utils.h" -#include "utils.h" - -namespace art { - -bool ElfStripper::Strip(File* file, std::string* error_msg) { - std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, error_msg)); - if (elf_file.get() == nullptr) { - return false; - } - - // ELF files produced by MCLinker look roughly like this - // - // +------------+ - // | Elf32_Ehdr | contains number of Elf32_Shdr and offset to first - // +------------+ - // | Elf32_Phdr | program headers - // | Elf32_Phdr | - // | ... | - // | Elf32_Phdr | - // +------------+ - // | section | mixture of needed and unneeded sections - // +------------+ - // | section | - // +------------+ - // | ... | - // +------------+ - // | section | - // +------------+ - // | Elf32_Shdr | section headers - // | Elf32_Shdr | - // | ... | contains offset to section start - // | Elf32_Shdr | - // +------------+ - // - // To strip: - // - leave the Elf32_Ehdr and Elf32_Phdr values in place. - // - walk the sections making a new set of Elf32_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 Elf32_Shdr section headers to end of file, updating Elf32_Ehdr - // - truncate rest of file - // - - std::vector<Elf32_Shdr> section_headers; - std::vector<Elf32_Word> section_headers_original_indexes; - section_headers.reserve(elf_file->GetSectionHeaderNum()); - - - Elf32_Shdr* string_section = elf_file->GetSectionNameStringSection(); - CHECK(string_section != nullptr); - for (Elf32_Word i = 0; i < elf_file->GetSectionHeaderNum(); i++) { - Elf32_Shdr* sh = elf_file->GetSectionHeader(i); - CHECK(sh != nullptr); - const char* name = elf_file->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; - } - if (StartsWith(name, ".debug") - || (strcmp(name, ".strtab") == 0) - || (strcmp(name, ".symtab") == 0)) { - 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(elf_file->GetSectionHeader(1) != nullptr); - Elf32_Off offset = elf_file->GetSectionHeader(1)->sh_offset; - for (size_t i = 1; i < section_headers.size(); i++) { - Elf32_Shdr& new_sh = section_headers[i]; - Elf32_Shdr* old_sh = elf_file->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(elf_file->Begin() + offset, - elf_file->Begin() + old_sh->sh_offset, - old_sh->sh_size); - new_sh.sh_offset = offset; - offset += old_sh->sh_size; - } - - Elf32_Off shoff = offset; - size_t section_headers_size_in_bytes = section_headers.size() * sizeof(Elf32_Shdr); - memcpy(elf_file->Begin() + offset, §ion_headers[0], section_headers_size_in_bytes); - offset += section_headers_size_in_bytes; - - elf_file->GetHeader().e_shnum = section_headers.size(); - elf_file->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; -} - -} // namespace art |