16a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom/* 26a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Copyright (C) 2012 The Android Open Source Project 36a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 46a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 56a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * you may not use this file except in compliance with the License. 66a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * You may obtain a copy of the License at 76a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 86a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 96a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * 106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * Unless required by applicable law or agreed to in writing, software 116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * See the License for the specific language governing permissions and 146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom * limitations under the License. 156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom */ 166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "elf_writer_mclinker.h" 186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <llvm/Support/TargetSelect.h> 206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/Environment.h> 226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/IRBuilder.h> 236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/Linker.h> 246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/LinkerConfig.h> 256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/MC/ZOption.h> 266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/Module.h> 276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/Support/Path.h> 286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include <mcld/Support/TargetSelect.h> 296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/unix_file/fd_file.h" 317f55288906c21b99801d75bb6fe17fe25af5c1e9Brian Carlstrom#include "class_linker.h" 327f55288906c21b99801d75bb6fe17fe25af5c1e9Brian Carlstrom#include "dex_method_iterator.h" 337940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 347f55288906c21b99801d75bb6fe17fe25af5c1e9Brian Carlstrom#include "elf_file.h" 356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h" 36ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method.h" 37ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom#include "mirror/art_method-inl.h" 387f55288906c21b99801d75bb6fe17fe25af5c1e9Brian Carlstrom#include "mirror/object-inl.h" 39c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "oat_writer.h" 407f55288906c21b99801d75bb6fe17fe25af5c1e9Brian Carlstrom#include "scoped_thread_state_change.h" 41c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "vector_output_stream.h" 426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art { 446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian CarlstromElfWriterMclinker::ElfWriterMclinker(const CompilerDriver& driver, File* elf_file) 466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom : ElfWriter(driver, elf_file), oat_input_(NULL) {} 476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian CarlstromElfWriterMclinker::~ElfWriterMclinker() {} 496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrombool ElfWriterMclinker::Create(File* elf_file, 51c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom OatWriter& oat_writer, 526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<const DexFile*>& dex_files, 536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& android_root, 546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom bool is_host, 556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const CompilerDriver& driver) { 566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ElfWriterMclinker elf_writer(driver, elf_file); 57c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 60c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrombool ElfWriterMclinker::Write(OatWriter& oat_writer, 616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<const DexFile*>& dex_files, 626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& android_root, 636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom bool is_host) { 64c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom std::vector<uint8_t> oat_contents; 65c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom oat_contents.reserve(oat_writer.GetSize()); 66c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom VectorOutputStream output_stream("oat contents", oat_contents); 67c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom CHECK(oat_writer.Write(output_stream)); 68c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom CHECK_EQ(oat_writer.GetSize(), oat_contents.size()); 69c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom 706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom Init(); 716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom AddOatInput(oat_contents); 726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom AddMethodInputs(dex_files); 746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom AddRuntimeInputs(android_root, is_host); 756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#endif 766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!Link()) { 776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 79c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom oat_contents.clear(); 806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom FixupOatMethodOffsets(dex_files); 826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#endif 836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return true; 846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromstatic void InitializeLLVM() { 876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: this is lifted from art's compiler_llvm.cc, should be factored out 886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (kIsTargetBuild) { 896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::InitializeNativeTarget(); 906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: odd that there is no InitializeNativeTargetMC? 916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } else { 926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::InitializeAllTargets(); 936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::InitializeAllTargetMCs(); 946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::Init() { 986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string target_triple; 996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string target_cpu; 1006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string target_attr; 1016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CompilerDriver::InstructionSetToLLVMTarget(compiler_driver_->GetInstructionSet(), 1026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom target_triple, 1036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom target_cpu, 1046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom target_attr); 1056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Based on mclinker's llvm-mcld.cpp main() and LinkerTest 1076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // 1086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: LinkerTest uses mcld::Initialize(), but it does an 1096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // llvm::InitializeAllTargets, which we don't want. Basically we 1106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // want mcld::InitializeNative, but it doesn't exist yet, so we 1116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // inline the minimal we need here. 1126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom InitializeLLVM(); 1136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::InitializeAllTargets(); 1146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::InitializeAllLinkers(); 1156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::InitializeAllEmulations(); 1166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::InitializeAllDiagnostics(); 1176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_.reset(new mcld::LinkerConfig(target_triple)); 1196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(linker_config_.get() != NULL); 1206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->setCodeGenType(mcld::LinkerConfig::DynObj); 1216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->options().setSOName(elf_file_->GetPath()); 1226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // error on undefined symbols. 1246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: should this just be set if kIsDebugBuild? 1256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->options().setNoUndefined(true); 1266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (compiler_driver_->GetInstructionSet() == kMips) { 1286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // MCLinker defaults MIPS section alignment to 0x10000, not 1296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // 0x1000. The ABI says this is because the max page size is 1306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // general is 64k but that isn't true on Android. 1316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ZOption z_option; 1326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom z_option.setKind(mcld::ZOption::MaxPageSize); 1336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom z_option.setPageSize(kPageSize); 1346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->options().addZOption(z_option); 1356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: Wire up mcld DiagnosticEngine to LOG? 1386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->options().setColor(false); 1396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (false) { 1406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // enables some tracing of input file processing 1416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_config_->options().setTrace(true); 1426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 1436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Based on alone::Linker::config 1456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom module_.reset(new mcld::Module(linker_config_->options().soname())); 1466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(module_.get() != NULL); 1476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ir_builder_.reset(new mcld::IRBuilder(*module_.get(), *linker_config_.get())); 1486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(ir_builder_.get() != NULL); 1496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_.reset(new mcld::Linker()); 1506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(linker_.get() != NULL); 1516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom linker_->config(*linker_config_.get()); 1526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 1536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::AddOatInput(std::vector<uint8_t>& oat_contents) { 1556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Add an artificial memory input. Based on LinkerTest. 1566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom UniquePtr<OatFile> oat_file(OatFile::OpenMemory(oat_contents, elf_file_->GetPath())); 1576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(oat_file.get() != NULL) << elf_file_->GetPath(); 1586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const char* oat_data_start = reinterpret_cast<const char*>(&oat_file->GetOatHeader()); 1606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const size_t oat_data_length = oat_file->GetOatHeader().GetExecutableOffset(); 1616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const char* oat_code_start = oat_data_start + oat_data_length; 1626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const size_t oat_code_length = oat_file->Size() - oat_data_length; 1636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of oat_input? 1656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom oat_input_ = ir_builder_->CreateInput("oat contents", 1666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::sys::fs::Path("oat contents path"), 1676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input::Object); 1686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(oat_input_ != NULL); 1696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of null_section? 1716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::LDSection* null_section = ir_builder_->CreateELFHeader(*oat_input_, 1726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom "", 1736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::LDFileFormat::Null, 1746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::SHT_NULL, 1756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 0); 1766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(null_section != NULL); 1776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: we should split readonly data from readonly executable 1796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // code like .oat does. We need to control section layout with 1806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // linker script like functionality to guarantee references 1816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // between sections maintain relative position which isn't 1826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // possible right now with the mclinker APIs. 1836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(oat_code_start != NULL); 1846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // we need to ensure that oatdata is page aligned so when we 1866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // fixup the segment load addresses, they remain page aligned. 1876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t alignment = kPageSize; 1886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of text_section? 1906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::LDSection* text_section = ir_builder_->CreateELFHeader(*oat_input_, 1916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ".text", 1926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::SHT_PROGBITS, 1936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::SHF_EXECINSTR 1946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom | llvm::ELF::SHF_ALLOC, 1956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom alignment); 1966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(text_section != NULL); 1976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 1986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::SectionData* text_sectiondata = ir_builder_->CreateSectionData(*text_section); 1996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(text_sectiondata != NULL); 2006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: why does IRBuilder::CreateRegion take a non-const pointer? 2026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Fragment* text_fragment = ir_builder_->CreateRegion(const_cast<char*>(oat_data_start), 2036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom oat_file->Size()); 2046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(text_fragment != NULL); 2056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ir_builder_->AppendFragment(*text_fragment, *text_sectiondata); 2066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ir_builder_->AddSymbol(*oat_input_, 2086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom "oatdata", 2096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Object, 2106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Define, 2116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Global, 2126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom oat_data_length, // size 2136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 0, // offset 2146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom text_section); 2156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ir_builder_->AddSymbol(*oat_input_, 2176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom "oatexec", 2186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Function, 2196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Define, 2206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Global, 2216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom oat_code_length, // size 2226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom oat_data_length, // offset 2236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom text_section); 2246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ir_builder_->AddSymbol(*oat_input_, 2266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom "oatlastword", 2276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Object, 2286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Define, 2296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::ResolveInfo::Global, 2306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 0, // size 2316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // subtract a word so symbol is within section 2326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom (oat_data_length + oat_code_length) - sizeof(uint32_t), // offset 2336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom text_section); 2346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 2356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 2376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::AddMethodInputs(const std::vector<const DexFile*>& dex_files) { 2386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DCHECK(oat_input_ != NULL); 2396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DexMethodIterator it(dex_files); 2416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom while (it.HasNext()) { 2426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const DexFile& dex_file = it.GetDexFile(); 2436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 2446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const CompiledMethod* compiled_method = 2453693c086ad4d5ba13ffcc7c7f481b21f67543660Brian Carlstrom compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, method_idx)); 2466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (compiled_method != NULL) { 2476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom AddCompiledCodeInput(*compiled_method); 2486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom it.Next(); 2506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom added_symbols_.clear(); 2526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 2536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::AddCompiledCodeInput(const CompiledCode& compiled_code) { 2556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Check if we've seen this compiled code before. If so skip 2566a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // it. This can happen for reused code such as invoke stubs. 2576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& symbol = compiled_code.GetSymbol(); 2586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom SafeMap<const std::string*, const std::string*>::iterator it = added_symbols_.find(&symbol); 2596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (it != added_symbols_.end()) { 2606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return; 2616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom added_symbols_.Put(&symbol, &symbol); 2636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Add input to supply code for symbol 2656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<uint8_t>& code = compiled_code.GetCode(); 2666a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of code_input? 2676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: why does IRBuilder::ReadInput take a non-const pointer? 2686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input* code_input = ir_builder_->ReadInput(symbol, 2696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const_cast<uint8_t*>(&code[0]), 2706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom code.size()); 2716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(code_input != NULL); 2726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 2736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::AddRuntimeInputs(const std::string& android_root, bool is_host) { 2756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string libart_so(android_root); 2766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libart_so += kIsDebugBuild ? "/lib/libartd.so" : "/lib/libart.so"; 2776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of libart_so_input? 2786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input* libart_so_input = ir_builder_->ReadInput(libart_so, libart_so); 2796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(libart_so_input != NULL); 2806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string host_prebuilt_dir("prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6"); 2826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string compiler_runtime_lib; 2846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (is_host) { 2856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom compiler_runtime_lib += host_prebuilt_dir; 2866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom compiler_runtime_lib += "/lib/gcc/i686-linux/4.6.x-google/libgcc.a"; 2876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } else { 2886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom compiler_runtime_lib += android_root; 2896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom compiler_runtime_lib += "/lib/libcompiler_rt.a"; 2906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 2916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of compiler_runtime_lib_input? 2926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input* compiler_runtime_lib_input = ir_builder_->ReadInput(compiler_runtime_lib, 2936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom compiler_runtime_lib); 2946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(compiler_runtime_lib_input != NULL); 2956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 2966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string libc_lib; 2976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (is_host) { 2986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libc_lib += host_prebuilt_dir; 2996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libc_lib += "/sysroot/usr/lib/libc.so.6"; 3006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } else { 3016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libc_lib += android_root; 3026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libc_lib += "/lib/libc.so"; 3036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of libc_lib_input? 3056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input* libc_lib_input_input = ir_builder_->ReadInput(libc_lib, libc_lib); 3066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(libc_lib_input_input != NULL); 3076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom std::string libm_lib; 3096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (is_host) { 3106a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libm_lib += host_prebuilt_dir; 3116a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libm_lib += "/sysroot/usr/lib/libm.so"; 3126a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } else { 3136a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libm_lib += android_root; 3146a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom libm_lib += "/lib/libm.so"; 3156a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3166a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: ownership of libm_lib_input? 3176a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Input* libm_lib_input_input = ir_builder_->ReadInput(libm_lib, libm_lib); 3186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(libm_lib_input_input != NULL); 3196a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 3206a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#endif 3216a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrombool ElfWriterMclinker::Link() { 3236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // link inputs 3246a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!linker_->link(*module_.get(), *ir_builder_.get())) { 3256a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(ERROR) << "Failed to link " << elf_file_->GetPath(); 3266a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 3276a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3286a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3296a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // emit linked output 3306a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // TODO: avoid dup of fd by fixing Linker::emit to not close the argument fd. 3316a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom int fd = dup(elf_file_->Fd()); 3326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (fd == -1) { 3336a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom PLOG(ERROR) << "Failed to dup file descriptor for " << elf_file_->GetPath(); 3346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 3356a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (!linker_->emit(fd)) { 3376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(ERROR) << "Failed to emit " << elf_file_->GetPath(); 3386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return false; 3396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mcld::Finalize(); 3416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom LOG(INFO) << "ELF file written successfully: " << elf_file_->GetPath(); 3426a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return true; 3436a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 3446a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3456a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#if defined(ART_USE_PORTABLE_COMPILER) 3466a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromvoid ElfWriterMclinker::FixupOatMethodOffsets(const std::vector<const DexFile*>& dex_files) { 3476a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom UniquePtr<ElfFile> elf_file(ElfFile::Open(elf_file_, true, false)); 3486a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(elf_file.get() != NULL) << elf_file_->GetPath(); 3496a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3506a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Addr oatdata_address = GetOatDataAddress(elf_file.get()); 3516a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom DexMethodIterator it(dex_files); 3526a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom while (it.HasNext()) { 3536a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const DexFile& dex_file = it.GetDexFile(); 3546a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t method_idx = it.GetMemberIndex(); 3556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom InvokeType invoke_type = it.GetInvokeType(); 356ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method = NULL; 3576a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (compiler_driver_->IsImage()) { 3586a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ClassLinker* linker = Runtime::Current()->GetClassLinker(); 3596a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom mirror::DexCache* dex_cache = linker->FindDexCache(dex_file); 3606a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Unchecked as we hold mutator_lock_ on entry. 3616a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom ScopedObjectAccessUnchecked soa(Thread::Current()); 3626a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom method = linker->ResolveMethod(dex_file, method_idx, dex_cache, NULL, NULL, invoke_type); 3636a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK(method != NULL); 3646a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3656a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const CompiledMethod* compiled_method = 3663693c086ad4d5ba13ffcc7c7f481b21f67543660Brian Carlstrom compiler_driver_->GetCompiledMethod(MethodReference(&dex_file, method_idx)); 3676a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (compiled_method != NULL) { 3686a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t offset = FixupCompiledCodeOffset(*elf_file.get(), oatdata_address, *compiled_method); 3696a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom // Don't overwrite static method trampoline 3706a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (method != NULL && 3716a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom (!method->IsStatic() || 3726a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom method->IsConstructor() || 3736a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom method->GetDeclaringClass()->IsInitialized())) { 3746a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom method->SetOatCodeOffset(offset); 3756a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3766a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3776a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom it.Next(); 3786a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3796a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom symbol_to_compiled_code_offset_.clear(); 3806a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 3816a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3826a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromuint32_t ElfWriterMclinker::FixupCompiledCodeOffset(ElfFile& elf_file, 3836a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Addr oatdata_address, 3846a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const CompiledCode& compiled_code) { 3856a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::string& symbol = compiled_code.GetSymbol(); 3866a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom SafeMap<const std::string*, uint32_t>::iterator it = symbol_to_compiled_code_offset_.find(&symbol); 3876a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom if (it != symbol_to_compiled_code_offset_.end()) { 3886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return it->second; 3896a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 3906a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3916a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom llvm::ELF::Elf32_Addr compiled_code_address = elf_file.FindSymbolAddress(llvm::ELF::SHT_SYMTAB, 3926a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom symbol, 3936a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom true); 3946a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK_NE(0U, compiled_code_address) << symbol; 3956a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom CHECK_LT(oatdata_address, compiled_code_address) << symbol; 3966a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t compiled_code_offset = compiled_code_address - oatdata_address; 3976a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom symbol_to_compiled_code_offset_.Put(&symbol, compiled_code_offset); 3986a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 3996a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom const std::vector<uint32_t>& offsets = compiled_code.GetOatdataOffsetsToCompliledCodeOffset(); 4006a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom for (uint32_t i = 0; i < offsets.size(); i++) { 4016a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t oatdata_offset = oatdata_address + offsets[i]; 4026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom uint32_t* addr = reinterpret_cast<uint32_t*>(elf_file.Begin() + oatdata_offset); 4036a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom *addr = compiled_code_offset; 4046a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom } 4056a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom return compiled_code_offset; 4066a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} 4076a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#endif 4086a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 4096a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} // namespace art 410