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