Remove ExtractCodeAndPrelink and switch Portable to MCLinker
Change-Id: Ia2459c7da6b79e0a1c0f1148c6e28ad9cbbe27a2
diff --git a/src/compiler/llvm/llvm_compilation_unit.cc b/src/compiler/llvm/llvm_compilation_unit.cc
index aad18fb..3783ae9 100644
--- a/src/compiler/llvm/llvm_compilation_unit.cc
+++ b/src/compiler/llvm/llvm_compilation_unit.cc
@@ -16,16 +16,11 @@
#include "llvm_compilation_unit.h"
-#include "base/logging.h"
-#include "compiled_method.h"
-#include "compiler_llvm.h"
-#include "instruction_set.h"
-#include "ir_builder.h"
-#include "os.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
-#include "runtime_support_builder_arm.h"
-#include "runtime_support_builder_thumb2.h"
-#include "runtime_support_builder_x86.h"
+#include <string>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/ADT/StringSet.h>
@@ -71,24 +66,30 @@
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <llvm/Transforms/Scalar.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#include <string>
+#include "base/logging.h"
+#include "base/unix_file/fd_file.h"
+#include "compiled_method.h"
+#include "compiler_llvm.h"
+#include "instruction_set.h"
+#include "ir_builder.h"
+#include "os.h"
+#include "runtime_support_builder_arm.h"
+#include "runtime_support_builder_thumb2.h"
+#include "runtime_support_builder_x86.h"
+#include "utils_llvm.h"
namespace art {
namespace llvm {
::llvm::FunctionPass*
CreateGBCExpanderPass(const IntrinsicHelper& intrinsic_helper, IRBuilder& irb,
- CompilerDriver* compiler, DexCompilationUnit* dex_compilation_unit);
+ CompilerDriver* compiler, const DexCompilationUnit* dex_compilation_unit);
::llvm::Module* makeLLVMModuleContents(::llvm::Module* module);
-LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_idx)
- : compiler_llvm_(compiler_llvm), cunit_idx_(cunit_idx) {
+LlvmCompilationUnit::LlvmCompilationUnit(const CompilerLLVM* compiler_llvm, size_t cunit_id)
+ : compiler_llvm_(compiler_llvm), cunit_id_(cunit_id) {
driver_ = NULL;
dex_compilation_unit_ = NULL;
llvm_info_.reset(new LLVMInfo());
@@ -136,27 +137,24 @@
bool LlvmCompilationUnit::Materialize() {
- std::string elf_image;
-
// Compile and prelink ::llvm::Module
- if (!MaterializeToString(elf_image)) {
- LOG(ERROR) << "Failed to materialize compilation unit " << cunit_idx_;
+ if (!MaterializeToString(elf_object_)) {
+ LOG(ERROR) << "Failed to materialize compilation unit " << cunit_id_;
return false;
}
-#if 0
- // Dump the ELF image for debugging
- std::string filename(StringPrintf("%s/Art%zu.elf",
- GetArtCacheOrDie(GetAndroidData()).c_str(),
- cunit_idx_));
- UniquePtr<File> output(OS::OpenFile(filename.c_str(), true));
- output->WriteFully(elf_image.data(), elf_image.size());
-#endif
-
- // Extract the .text section and prelink the code
- if (!ExtractCodeAndPrelink(elf_image)) {
- LOG(ERROR) << "Failed to extract code from compilation unit " << cunit_idx_;
- return false;
+ if (false) {
+ // Dump the ELF image for debugging
+ std::string directory;
+ if (kIsTargetBuild) {
+ directory += GetArtCacheOrDie(GetAndroidData());
+ } else {
+ directory += "/tmp";
+ }
+ std::string filename(StringPrintf("%s/Art%u.o", directory.c_str(), cunit_id_));
+ UniquePtr<File> output(OS::OpenFile(filename.c_str(), true));
+ output->WriteFully(elf_object_.data(), elf_object_.size());
+ LOG(INFO) << ".o file written successfully: " << filename;
}
return true;
@@ -284,112 +282,6 @@
return true;
}
-bool LlvmCompilationUnit::ExtractCodeAndPrelink(const std::string& elf_image) {
- if (GetInstructionSet() == kX86) {
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- compiled_code_.push_back(0xccU);
- return true;
- }
-
- ::llvm::OwningPtr< ::llvm::MemoryBuffer> elf_image_buff(
- ::llvm::MemoryBuffer::getMemBuffer(::llvm::StringRef(elf_image.data(),
- elf_image.size())));
-
- ::llvm::OwningPtr< ::llvm::object::ObjectFile> elf_file(
- ::llvm::object::ObjectFile::createELFObjectFile(elf_image_buff.take()));
-
- ::llvm::error_code ec;
-
- const ProcedureLinkageTable& plt = compiler_llvm_->GetProcedureLinkageTable();
-
- for (::llvm::object::section_iterator
- sec_iter = elf_file->begin_sections(),
- sec_end = elf_file->end_sections();
- sec_iter != sec_end; sec_iter.increment(ec)) {
-
- CHECK(ec == 0) << "Failed to read section because " << ec.message();
-
- // Read the section information
- ::llvm::StringRef name;
- uint64_t alignment = 0u;
- uint64_t size = 0u;
-
- CHECK(sec_iter->getName(name) == 0);
- CHECK(sec_iter->getSize(size) == 0);
- CHECK(sec_iter->getAlignment(alignment) == 0);
-
- if (name == ".data" || name == ".bss" || name == ".rodata") {
- if (size > 0) {
- LOG(FATAL) << "Compilation unit " << cunit_idx_ << " has non-empty "
- << name.str() << " section";
- }
-
- } else if (name == "" || name == ".rel.text" ||
- name == ".ARM.attributes" || name == ".symtab" ||
- name == ".strtab" || name == ".shstrtab") {
- // We can ignore these sections. We don't have to copy them into
- // the result Oat file.
-
- } else if (name == ".text") {
- // Ensure the alignment requirement is less than or equal to
- // kArchAlignment
- CheckCodeAlign(alignment);
-
- // Copy the compiled code
- ::llvm::StringRef contents;
- CHECK(sec_iter->getContents(contents) == 0);
-
- copy(contents.data(),
- contents.data() + contents.size(),
- back_inserter(compiled_code_));
-
- // Prelink the compiled code
- for (::llvm::object::relocation_iterator
- rel_iter = sec_iter->begin_relocations(),
- rel_end = sec_iter->end_relocations(); rel_iter != rel_end;
- rel_iter.increment(ec)) {
-
- CHECK(ec == 0) << "Failed to read relocation because " << ec.message();
-
- // Read the relocation information
- ::llvm::object::SymbolRef sym_ref;
- uint64_t rel_offset = 0;
- uint64_t rel_type = 0;
- int64_t rel_addend = 0;
-
- CHECK(rel_iter->getSymbol(sym_ref) == 0);
- CHECK(rel_iter->getOffset(rel_offset) == 0);
- CHECK(rel_iter->getType(rel_type) == 0);
- CHECK(rel_iter->getAdditionalInfo(rel_addend) == 0);
-
- // Read the symbol related to this relocation fixup
- ::llvm::StringRef sym_name;
- CHECK(sym_ref.getName(sym_name) == 0);
-
- // Relocate the fixup.
- // TODO: Support more relocation type.
- CHECK(rel_type == ::llvm::ELF::R_ARM_ABS32);
- CHECK_LE(rel_offset + 4, compiled_code_.size());
-
- uintptr_t dest_addr = plt.GetEntryAddress(sym_name.str().c_str());
- uintptr_t final_addr = dest_addr + rel_addend;
- compiled_code_[rel_offset] = final_addr & 0xff;
- compiled_code_[rel_offset + 1] = (final_addr >> 8) & 0xff;
- compiled_code_[rel_offset + 2] = (final_addr >> 16) & 0xff;
- compiled_code_[rel_offset + 3] = (final_addr >> 24) & 0xff;
- }
-
- } else {
- LOG(WARNING) << "Unexpected section: " << name.str();
- }
- }
-
- return true;
-}
-
-
// Check whether the align is less than or equal to the code alignment of
// that architecture. Since the Oat writer only guarantee that the compiled
// method being aligned to kArchAlignment, we have no way to align the ELf