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_quick.h" 186a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 19e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban#include <unordered_map> 20626a1666015b0fa201e979870baf06afa93b65e7David Srbecky#include <unordered_set> 21e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban 22f8980875ef8fb0ce86be4ed2c0af7070f5ae9cfdDavid Srbecky#include "base/casts.h" 236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/logging.h" 2410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko#include "base/stl_util.h" 2520f85597828194c12be10d3a927999def066555eVladimir Marko#include "compiled_method.h" 26c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_writer.h" 274fda4eb799c95be266f52aaf3461a440ea86b841David Srbecky#include "debug/method_debug_info.h" 2820f85597828194c12be10d3a927999def066555eVladimir Marko#include "driver/compiler_options.h" 2910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko#include "elf.h" 3054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe#include "elf_builder.h" 3150cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#include "elf_utils.h" 326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h" 3379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe#include "leb128.h" 34131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko#include "linker/buffered_output_stream.h" 35131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko#include "linker/file_output_stream.h" 360c4572e8c874de279463af22268d588471f40d3eDavid Srbecky#include "thread-inl.h" 370c4572e8c874de279463af22268d588471f40d3eDavid Srbecky#include "thread_pool.h" 386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "utils.h" 396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art { 416a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 42ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// .eh_frame and .debug_frame are almost identical. 43ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// Except for some minor formatting differences, the main difference 44ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// is that .eh_frame is allocated within the running program because 45ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// it is used by C++ exception handling (which we do not use so we 46ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// can choose either). C++ compilers generally tend to use .eh_frame 47ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// because if they need it sometimes, they might as well always use it. 48aaf143d80bc6f226290eadb10361a752ed5d204eDavid Srbecky// Let's use .debug_frame because it is easier to strip or compress. 49aaf143d80bc6f226290eadb10361a752ed5d204eDavid Srbeckyconstexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT; 50ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky 510c4572e8c874de279463af22268d588471f40d3eDavid Srbeckyclass DebugInfoTask : public Task { 520c4572e8c874de279463af22268d588471f40d3eDavid Srbecky public: 530c4572e8c874de279463af22268d588471f40d3eDavid Srbecky DebugInfoTask(InstructionSet isa, 545d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 550c4572e8c874de279463af22268d588471f40d3eDavid Srbecky size_t rodata_section_size, 560c4572e8c874de279463af22268d588471f40d3eDavid Srbecky size_t text_section_size, 57c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky const ArrayRef<const debug::MethodDebugInfo>& method_infos) 580c4572e8c874de279463af22268d588471f40d3eDavid Srbecky : isa_(isa), 595d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky instruction_set_features_(features), 600c4572e8c874de279463af22268d588471f40d3eDavid Srbecky rodata_section_size_(rodata_section_size), 610c4572e8c874de279463af22268d588471f40d3eDavid Srbecky text_section_size_(text_section_size), 620c4572e8c874de279463af22268d588471f40d3eDavid Srbecky method_infos_(method_infos) { 630c4572e8c874de279463af22268d588471f40d3eDavid Srbecky } 640c4572e8c874de279463af22268d588471f40d3eDavid Srbecky 650c4572e8c874de279463af22268d588471f40d3eDavid Srbecky void Run(Thread*) { 66c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky result_ = debug::MakeMiniDebugInfo(isa_, 675d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky instruction_set_features_, 680c4572e8c874de279463af22268d588471f40d3eDavid Srbecky rodata_section_size_, 690c4572e8c874de279463af22268d588471f40d3eDavid Srbecky text_section_size_, 700c4572e8c874de279463af22268d588471f40d3eDavid Srbecky method_infos_); 710c4572e8c874de279463af22268d588471f40d3eDavid Srbecky } 720c4572e8c874de279463af22268d588471f40d3eDavid Srbecky 730c4572e8c874de279463af22268d588471f40d3eDavid Srbecky std::vector<uint8_t>* GetResult() { 740c4572e8c874de279463af22268d588471f40d3eDavid Srbecky return &result_; 750c4572e8c874de279463af22268d588471f40d3eDavid Srbecky } 760c4572e8c874de279463af22268d588471f40d3eDavid Srbecky 770c4572e8c874de279463af22268d588471f40d3eDavid Srbecky private: 780c4572e8c874de279463af22268d588471f40d3eDavid Srbecky InstructionSet isa_; 795d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* instruction_set_features_; 800c4572e8c874de279463af22268d588471f40d3eDavid Srbecky size_t rodata_section_size_; 810c4572e8c874de279463af22268d588471f40d3eDavid Srbecky size_t text_section_size_; 82c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky const ArrayRef<const debug::MethodDebugInfo>& method_infos_; 830c4572e8c874de279463af22268d588471f40d3eDavid Srbecky std::vector<uint8_t> result_; 840c4572e8c874de279463af22268d588471f40d3eDavid Srbecky}; 850c4572e8c874de279463af22268d588471f40d3eDavid Srbecky 86533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes> 8710c13565474de2786aad7c2e79757ea250747a15Vladimir Markoclass ElfWriterQuick FINAL : public ElfWriter { 8810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko public: 8910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ElfWriterQuick(InstructionSet instruction_set, 905d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 9110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko const CompilerOptions* compiler_options, 9210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko File* elf_file); 9310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko ~ElfWriterQuick(); 9410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 9510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko void Start() OVERRIDE; 96944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko void SetLoadedSectionSizes(size_t rodata_size, size_t text_size, size_t bss_size) OVERRIDE; 97944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko void PrepareDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE; 9810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko OutputStream* StartRoData() OVERRIDE; 9910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko void EndRoData(OutputStream* rodata) OVERRIDE; 10010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko OutputStream* StartText() OVERRIDE; 10110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko void EndText(OutputStream* text) OVERRIDE; 10210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko void WriteDynamicSection() OVERRIDE; 103c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky void WriteDebugInfo(const ArrayRef<const debug::MethodDebugInfo>& method_infos) OVERRIDE; 10410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko void WritePatchLocations(const ArrayRef<const uintptr_t>& patch_locations) OVERRIDE; 10510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko bool End() OVERRIDE; 10610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 107131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko virtual OutputStream* GetStream() OVERRIDE; 108131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko 109944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t GetLoadedSize() OVERRIDE; 110944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko 11110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko static void EncodeOatPatches(const std::vector<uintptr_t>& locations, 11210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko std::vector<uint8_t>* buffer); 11310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 11410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko private: 1155d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* instruction_set_features_; 11610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko const CompilerOptions* const compiler_options_; 11710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko File* const elf_file_; 118944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t rodata_size_; 119944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t text_size_; 120944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t bss_size_; 12110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko std::unique_ptr<BufferedOutputStream> output_stream_; 12210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko std::unique_ptr<ElfBuilder<ElfTypes>> builder_; 1230c4572e8c874de279463af22268d588471f40d3eDavid Srbecky std::unique_ptr<DebugInfoTask> debug_info_task_; 1240c4572e8c874de279463af22268d588471f40d3eDavid Srbecky std::unique_ptr<ThreadPool> debug_info_thread_pool_; 12510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 12610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick); 12710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko}; 12810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 12910c13565474de2786aad7c2e79757ea250747a15Vladimir Markostd::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set, 1305d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 13110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko const CompilerOptions* compiler_options, 13210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko File* elf_file) { 13310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko if (Is64BitInstructionSet(instruction_set)) { 1345d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set, 1355d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky features, 1365d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky compiler_options, 1375d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky elf_file); 13810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko } else { 1395d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set, 1405d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky features, 1415d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky compiler_options, 1425d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky elf_file); 14310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko } 144b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 145b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom 146533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes> 14710c13565474de2786aad7c2e79757ea250747a15Vladimir MarkoElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set, 1485d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 14910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko const CompilerOptions* compiler_options, 15010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko File* elf_file) 15110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko : ElfWriter(), 1525d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky instruction_set_features_(features), 15310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko compiler_options_(compiler_options), 15410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko elf_file_(elf_file), 155944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko rodata_size_(0u), 156944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko text_size_(0u), 157944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko bss_size_(0u), 15810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko output_stream_(MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))), 1595d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky builder_(new ElfBuilder<ElfTypes>(instruction_set, features, output_stream_.get())) {} 16054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe 161533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes> 16210c13565474de2786aad7c2e79757ea250747a15Vladimir MarkoElfWriterQuick<ElfTypes>::~ElfWriterQuick() {} 163bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky 16410c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 16510c13565474de2786aad7c2e79757ea250747a15Vladimir Markovoid ElfWriterQuick<ElfTypes>::Start() { 16610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko builder_->Start(); 16710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 16810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 16910c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 170944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Markovoid ElfWriterQuick<ElfTypes>::SetLoadedSectionSizes(size_t rodata_size, 171944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t text_size, 172944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko size_t bss_size) { 173944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko DCHECK_EQ(rodata_size_, 0u); 174944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko rodata_size_ = rodata_size; 175944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko DCHECK_EQ(text_size_, 0u); 176944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko text_size_ = text_size; 177944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko DCHECK_EQ(bss_size_, 0u); 178944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko bss_size_ = bss_size; 179944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko builder_->PrepareDynamicSection(elf_file_->GetPath(), rodata_size_, text_size_, bss_size_); 180944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko} 181944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko 182944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Markotemplate <typename ElfTypes> 18310c13565474de2786aad7c2e79757ea250747a15Vladimir MarkoOutputStream* ElfWriterQuick<ElfTypes>::StartRoData() { 18410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko auto* rodata = builder_->GetRoData(); 1856d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky rodata->Start(); 18610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko return rodata; 18710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 188bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky 18910c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 19010c13565474de2786aad7c2e79757ea250747a15Vladimir Markovoid ElfWriterQuick<ElfTypes>::EndRoData(OutputStream* rodata) { 19110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko CHECK_EQ(builder_->GetRoData(), rodata); 19210c13565474de2786aad7c2e79757ea250747a15Vladimir Marko builder_->GetRoData()->End(); 19310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 19410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 19510c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 19610c13565474de2786aad7c2e79757ea250747a15Vladimir MarkoOutputStream* ElfWriterQuick<ElfTypes>::StartText() { 19710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko auto* text = builder_->GetText(); 1986d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky text->Start(); 19910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko return text; 20010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 20110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko 20210c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 20310c13565474de2786aad7c2e79757ea250747a15Vladimir Markovoid ElfWriterQuick<ElfTypes>::EndText(OutputStream* text) { 20410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko CHECK_EQ(builder_->GetText(), text); 20510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko builder_->GetText()->End(); 20610c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 207033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky 20810c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 20945724f9a0cc38dbb3071beb3eeab96499868b49cVladimir Markovoid ElfWriterQuick<ElfTypes>::WriteDynamicSection() { 210944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko if (bss_size_ != 0u) { 211944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko builder_->GetBss()->WriteNoBitsSection(bss_size_); 212944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko } 213316a2186b7fa9e03187d45ac0fa320f4dff1f3dfDouglas Leung if (builder_->GetIsa() == kMips || builder_->GetIsa() == kMips64) { 214316a2186b7fa9e03187d45ac0fa320f4dff1f3dfDouglas Leung builder_->WriteMIPSabiflagsSection(); 215316a2186b7fa9e03187d45ac0fa320f4dff1f3dfDouglas Leung } 216944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko builder_->WriteDynamicSection(); 21710c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 218bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky 21910c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 2200c4572e8c874de279463af22268d588471f40d3eDavid Srbeckyvoid ElfWriterQuick<ElfTypes>::PrepareDebugInfo( 221c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky const ArrayRef<const debug::MethodDebugInfo>& method_infos) { 222370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky if (!method_infos.empty() && compiler_options_->GetGenerateMiniDebugInfo()) { 2230c4572e8c874de279463af22268d588471f40d3eDavid Srbecky // Prepare the mini-debug-info in background while we do other I/O. 2240c4572e8c874de279463af22268d588471f40d3eDavid Srbecky Thread* self = Thread::Current(); 2250c4572e8c874de279463af22268d588471f40d3eDavid Srbecky debug_info_task_ = std::unique_ptr<DebugInfoTask>( 2265d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky new DebugInfoTask(builder_->GetIsa(), 2275d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky instruction_set_features_, 2285d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky rodata_size_, 2295d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky text_size_, 2305d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky method_infos)); 2310c4572e8c874de279463af22268d588471f40d3eDavid Srbecky debug_info_thread_pool_ = std::unique_ptr<ThreadPool>( 2320c4572e8c874de279463af22268d588471f40d3eDavid Srbecky new ThreadPool("Mini-debug-info writer", 1)); 2330c4572e8c874de279463af22268d588471f40d3eDavid Srbecky debug_info_thread_pool_->AddTask(self, debug_info_task_.get()); 2340c4572e8c874de279463af22268d588471f40d3eDavid Srbecky debug_info_thread_pool_->StartWorkers(self); 2350c4572e8c874de279463af22268d588471f40d3eDavid Srbecky } 2360c4572e8c874de279463af22268d588471f40d3eDavid Srbecky} 2370c4572e8c874de279463af22268d588471f40d3eDavid Srbecky 2380c4572e8c874de279463af22268d588471f40d3eDavid Srbeckytemplate <typename ElfTypes> 23910c13565474de2786aad7c2e79757ea250747a15Vladimir Markovoid ElfWriterQuick<ElfTypes>::WriteDebugInfo( 240c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky const ArrayRef<const debug::MethodDebugInfo>& method_infos) { 241370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky if (!method_infos.empty()) { 242370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky if (compiler_options_->GetGenerateDebugInfo()) { 243370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky // Generate all the debug information we can. 244c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky debug::WriteDebugInfo(builder_.get(), method_infos, kCFIFormat, true /* write_oat_patches */); 245370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky } 246370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky if (compiler_options_->GetGenerateMiniDebugInfo()) { 247370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky // Wait for the mini-debug-info generation to finish and write it to disk. 248370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky Thread* self = Thread::Current(); 249370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky DCHECK(debug_info_thread_pool_ != nullptr); 250370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky debug_info_thread_pool_->Wait(self, true, false); 251370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky builder_->WriteSection(".gnu_debugdata", debug_info_task_->GetResult()); 252370339cb8edd91ec8732e0c97cea1f0556cfcc11David Srbecky } 2535b1c2ca30dad519be285f0a1e839c23cc4e3a51dDavid Srbecky } 25410c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 2556a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom 25610c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 25710c13565474de2786aad7c2e79757ea250747a15Vladimir Markovoid ElfWriterQuick<ElfTypes>::WritePatchLocations( 25810c13565474de2786aad7c2e79757ea250747a15Vladimir Marko const ArrayRef<const uintptr_t>& patch_locations) { 259f8980875ef8fb0ce86be4ed2c0af7070f5ae9cfdDavid Srbecky // Add relocation section for .text. 26010c13565474de2786aad7c2e79757ea250747a15Vladimir Marko if (compiler_options_->GetIncludePatchInformation()) { 261f8980875ef8fb0ce86be4ed2c0af7070f5ae9cfdDavid Srbecky // Note that ElfWriter::Fixup will be called regardless and therefore 262f8980875ef8fb0ce86be4ed2c0af7070f5ae9cfdDavid Srbecky // we need to include oat_patches for debug sections unconditionally. 26310c13565474de2786aad7c2e79757ea250747a15Vladimir Marko builder_->WritePatches(".text.oat_patches", patch_locations); 26453cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light } 26510c13565474de2786aad7c2e79757ea250747a15Vladimir Marko} 26653cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light 26710c13565474de2786aad7c2e79757ea250747a15Vladimir Markotemplate <typename ElfTypes> 26810c13565474de2786aad7c2e79757ea250747a15Vladimir Markobool ElfWriterQuick<ElfTypes>::End() { 26910c13565474de2786aad7c2e79757ea250747a15Vladimir Marko builder_->End(); 2706d8c8f0344a706df651567387ede683ab3ec1b5fDavid Srbecky 27110c13565474de2786aad7c2e79757ea250747a15Vladimir Marko return builder_->Good(); 272b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom} 273ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell 274533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes> 275131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir MarkoOutputStream* ElfWriterQuick<ElfTypes>::GetStream() { 276131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko return builder_->GetStream(); 277131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko} 278131980fc9aeb2b4d03480443e0fb494c76ce03a2Vladimir Marko 279944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Markotemplate <typename ElfTypes> 280944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Markosize_t ElfWriterQuick<ElfTypes>::GetLoadedSize() { 281944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko return builder_->GetLoadedSize(); 282944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko} 283944da603cde59a4277f3bbc31d860a90842a1a2aVladimir Marko 284f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray// Explicit instantiations 285533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate class ElfWriterQuick<ElfTypes32>; 286533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate class ElfWriterQuick<ElfTypes64>; 287f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray 2886a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom} // namespace art 289