1700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom/* 2700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Copyright (C) 2012 The Android Open Source Project 3700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * 4700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License"); 5700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * you may not use this file except in compliance with the License. 6700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * You may obtain a copy of the License at 7700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * 8700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * http://www.apache.org/licenses/LICENSE-2.0 9700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * 10700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * Unless required by applicable law or agreed to in writing, software 11700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS, 12700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * See the License for the specific language governing permissions and 14700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom * limitations under the License. 15700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom */ 16700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 17700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom#include "elf_writer.h" 18700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 193d21bdf8894e780d349c481e5c9e29fe1556051cMathieu Chartier#include "art_method-inl.h" 20265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "base/unix_file/fd_file.h" 21265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "class_linker.h" 22225ade2eef559a8609879f142789a4f59aec5704Ian Rogers#include "dex_file-inl.h" 23265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "dex_method_iterator.h" 247940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h" 25265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "elf_file.h" 26265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "invoke_type.h" 27225ade2eef559a8609879f142789a4f59aec5704Ian Rogers#include "mirror/object-inl.h" 28265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "oat.h" 29265091e581c9f643b37e7966890911f09e223269Brian Carlstrom#include "scoped_thread_state_change.h" 30265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 31700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromnamespace art { 32700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 3362d1ca3182a6cbb921799825f43ad36821233fd7Tong Shenuintptr_t ElfWriter::GetOatDataAddress(ElfFile* elf_file) { 3462d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen uintptr_t oatdata_address = elf_file->FindSymbolAddress(SHT_DYNSYM, 3550cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray "oatdata", 3650cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray false); 37265091e581c9f643b37e7966890911f09e223269Brian Carlstrom CHECK_NE(0U, oatdata_address); 38265091e581c9f643b37e7966890911f09e223269Brian Carlstrom return oatdata_address; 39265091e581c9f643b37e7966890911f09e223269Brian Carlstrom} 40265091e581c9f643b37e7966890911f09e223269Brian Carlstrom 41700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstromvoid ElfWriter::GetOatElfInformation(File* file, 42a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko size_t* oat_loaded_size, 43a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko size_t* oat_data_offset) { 448d31bbd3d6536de12bc20e3d29cfe03fe848f9daIan Rogers std::string error_msg; 45700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, false, false, &error_msg)); 463470ab4011b5e18d590d5375e2f13a1e3bd69222Alex Light CHECK(elf_file.get() != nullptr) << error_msg; 47700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 48a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko bool success = elf_file->GetLoadedSize(oat_loaded_size, &error_msg); 49a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko CHECK(success) << error_msg; 50a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko CHECK_NE(0U, *oat_loaded_size); 51a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko *oat_data_offset = GetOatDataAddress(elf_file.get()); 52a36098b3717e14baf6a173e72082f6ef3b7bcefdVladimir Marko CHECK_NE(0U, *oat_data_offset); 53700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} 54700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom 5562d1ca3182a6cbb921799825f43ad36821233fd7Tong Shenbool ElfWriter::Fixup(File* file, uintptr_t oat_data_begin) { 5662d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen std::string error_msg; 5762d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen std::unique_ptr<ElfFile> elf_file(ElfFile::Open(file, true, false, &error_msg)); 5862d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen CHECK(elf_file.get() != nullptr) << error_msg; 5962d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen 6062d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen // Lookup "oatdata" symbol address. 6162d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen uintptr_t oatdata_address = ElfWriter::GetOatDataAddress(elf_file.get()); 6262d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen uintptr_t base_address = oat_data_begin - oatdata_address; 6362d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen 6462d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen return elf_file->Fixup(base_address); 6562d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen} 6662d1ca3182a6cbb921799825f43ad36821233fd7Tong Shen 67700c8d31733534a3d978b75a03f6f7e177dc7e81Brian Carlstrom} // namespace art 68