elf_writer_quick.cc revision 388d2861ce185fe9bbf1989f1467031467bd1de7
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
226a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/logging.h"
236a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "base/unix_file/fd_file.h"
2420f85597828194c12be10d3a927999def066555eVladimir Marko#include "compiled_method.h"
250df9e1faed9b095b084c4eca6ee59d24fba21c9fDavid Srbecky#include "dex_file-inl.h"
267940e44f4517de5e2634a7e07d58d0fb26160513Brian Carlstrom#include "driver/compiler_driver.h"
2720f85597828194c12be10d3a927999def066555eVladimir Marko#include "driver/compiler_options.h"
2854fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe#include "elf_builder.h"
29e3ea83811d47152c00abea24a9b420651a33b496Yevgeny Rouban#include "elf_file.h"
3050cfe74daaece80853cb3b45d4338329b7d0345bNicolas Geoffray#include "elf_utils.h"
313b9d57ab580a0593635a7dbe3dd2e2c76274f9faDavid Srbecky#include "elf_writer_debug.h"
326a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "globals.h"
3379273802f2b788bcd3eb76edf4df1bcaa57f886fAndreas Gampe#include "leb128.h"
346a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "oat.h"
35c50d8e11a098cc5c6239aa86b47d4fcf8cbb4899Brian Carlstrom#include "oat_writer.h"
366a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom#include "utils.h"
376a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
386a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstromnamespace art {
396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
40ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// .eh_frame and .debug_frame are almost identical.
41ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// Except for some minor formatting differences, the main difference
42ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// is that .eh_frame is allocated within the running program because
43ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// it is used by C++ exception handling (which we do not use so we
44ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// can choose either).  C++ compilers generally tend to use .eh_frame
45ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky// because if they need it sometimes, they might as well always use it.
46ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbeckyconstexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_EH_FRAME_FORMAT;
47ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky
48388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// The ARM specification defines three special mapping symbols
49388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// $a, $t and $d which mark ARM, Thumb and data ranges respectively.
50388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// These symbols can be used by tools, for example, to pretty
51388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// print instructions correctly.  Objdump will use them if they
52388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// exist, but it will still work well without them.
53388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// However, these extra symbols take space, so let's just generate
54388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky// one symbol which marks the whole .text section as code.
55388d2861ce185fe9bbf1989f1467031467bd1de7David Srbeckyconstexpr bool kGenerateSingleArmMappingSymbol = true;
56388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky
57533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes>
58533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckybool ElfWriterQuick<ElfTypes>::Create(File* elf_file,
59533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky                                      OatWriter* oat_writer,
60533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky                                      const std::vector<const DexFile*>& dex_files,
61533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky                                      const std::string& android_root,
62533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky                                      bool is_host,
63533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky                                      const CompilerDriver& driver) {
64b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  ElfWriterQuick elf_writer(driver, elf_file);
65b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom  return elf_writer.Write(oat_writer, dex_files, android_root, is_host);
66b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom}
67b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom
68533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes>
69533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckystatic void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer);
7054fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
712f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky// Encode patch locations in .oat_patches format.
72533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes>
73533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckyvoid ElfWriterQuick<ElfTypes>::EncodeOatPatches(
74533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    const OatWriter::PatchLocationsMap& sections,
75533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    std::vector<uint8_t>* buffer) {
762f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky  for (const auto& section : sections) {
772f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    const std::string& name = section.first;
782f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    std::vector<uintptr_t>* locations = section.second.get();
792f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    DCHECK(!name.empty());
802f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    std::sort(locations->begin(), locations->end());
812f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    // Reserve buffer space - guess 2 bytes per ULEB128.
822f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    buffer->reserve(buffer->size() + name.size() + locations->size() * 2);
832f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    // Write null-terminated section name.
842f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    const uint8_t* name_data = reinterpret_cast<const uint8_t*>(name.c_str());
852f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    buffer->insert(buffer->end(), name_data, name_data + name.size() + 1);
862f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    // Write placeholder for data length.
872f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    size_t length_pos = buffer->size();
882f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    EncodeUnsignedLeb128(buffer, UINT32_MAX);
892f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    // Write LEB128 encoded list of advances (deltas between consequtive addresses).
902f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    size_t data_pos = buffer->size();
912f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    uintptr_t address = 0;  // relative to start of section.
922f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    for (uintptr_t location : *locations) {
932f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      DCHECK_LT(location - address, UINT32_MAX) << "Large gap between patch locations";
942f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      EncodeUnsignedLeb128(buffer, location - address);
952f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      address = location;
962f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    }
972f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    // Update length.
982f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    UpdateUnsignedLeb128(buffer->data() + length_pos, buffer->size() - data_pos);
992f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky  }
1002f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky  buffer->push_back(0);  // End of sections.
1012f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky}
1022f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky
103bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbeckyclass RodataWriter FINAL : public CodeOutput {
104bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky public:
105bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  explicit RodataWriter(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
106bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
107bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  bool Write(OutputStream* out) OVERRIDE {
108bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    return oat_writer_->WriteRodata(out);
109527c9c71f0c6e2f9943ac028e7c050500699a44bDavid Srbecky  }
110bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
111bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky private:
112bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  OatWriter* oat_writer_;
113bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky};
114bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
115bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbeckyclass TextWriter FINAL : public CodeOutput {
116bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky public:
117bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  explicit TextWriter(OatWriter* oat_writer) : oat_writer_(oat_writer) {}
118bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
119bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  bool Write(OutputStream* out) OVERRIDE {
120bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    return oat_writer_->WriteCode(out);
121bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  }
122bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
123bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky private:
124bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  OatWriter* oat_writer_;
125bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky};
126527c9c71f0c6e2f9943ac028e7c050500699a44bDavid Srbecky
127033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbeckyenum PatchResult {
128033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  kAbsoluteAddress,  // Absolute memory location.
129033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  kPointerRelativeAddress,  // Offset relative to the location of the pointer.
130033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  kSectionRelativeAddress,  // Offset relative to start of containing section.
131033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky};
132033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky
133033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky// Patch memory addresses within a buffer.
134033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky// It assumes that the unpatched addresses are offsets relative to base_address.
135033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky// (which generally means method's low_pc relative to the start of .text)
136033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbeckytemplate <typename Elf_Addr, typename Address, PatchResult kPatchResult>
137033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbeckystatic void Patch(const std::vector<uintptr_t>& patch_locations,
138033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                  Elf_Addr buffer_address, Elf_Addr base_address,
139033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                  std::vector<uint8_t>* buffer) {
140033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  for (uintptr_t location : patch_locations) {
141033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky    typedef __attribute__((__aligned__(1))) Address UnalignedAddress;
142033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky    auto* to_patch = reinterpret_cast<UnalignedAddress*>(buffer->data() + location);
143033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky    switch (kPatchResult) {
144033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky      case kAbsoluteAddress:
145033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        *to_patch = (base_address + *to_patch);
146033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        break;
147033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky      case kPointerRelativeAddress:
148033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        *to_patch = (base_address + *to_patch) - (buffer_address + location);
149033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        break;
150033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky      case kSectionRelativeAddress:
151033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        *to_patch = (base_address + *to_patch) - buffer_address;
152033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky        break;
153033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky    }
154033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  }
155033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky}
156033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky
157533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes>
158533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckybool ElfWriterQuick<ElfTypes>::Write(
159533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    OatWriter* oat_writer,
160533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED,
161533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    const std::string& android_root_unused ATTRIBUTE_UNUSED,
162533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky    bool is_host_unused ATTRIBUTE_UNUSED) {
163033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  using Elf_Addr = typename ElfTypes::Addr;
164bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const InstructionSet isa = compiler_driver_->GetInstructionSet();
165bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
166bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  // Setup the builder with the main OAT sections (.rodata .text .bss).
167bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const size_t rodata_size = oat_writer->GetOatHeader().GetExecutableOffset();
168bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const size_t text_size = oat_writer->GetSize() - rodata_size;
169bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const size_t bss_size = oat_writer->GetBssSize();
170bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  RodataWriter rodata_writer(oat_writer);
171bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  TextWriter text_writer(oat_writer);
172533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbecky  std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>(
173bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      isa, rodata_size, &rodata_writer, text_size, &text_writer, bss_size));
174bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky
175bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  // Add debug sections.
176bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  // They are stack allocated here (in the same scope as the builder),
177bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  // but they are registred with the builder only if they are used.
178bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  using RawSection = typename ElfBuilder<ElfTypes>::RawSection;
179bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const auto* text = builder->GetText();
180bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  const bool is64bit = Is64BitInstructionSet(isa);
181ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky  const int pointer_size = GetInstructionSetPointerSize(isa);
182033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0,
183033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                      is64bit ? Patch<Elf_Addr, uint64_t, kPointerRelativeAddress> :
184033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                                Patch<Elf_Addr, uint32_t, kPointerRelativeAddress>,
185033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                      text);
186033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection eh_frame_hdr(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0,
187033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                          Patch<Elf_Addr, uint32_t, kSectionRelativeAddress>, text);
188ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky  RawSection debug_frame(".debug_frame", SHT_PROGBITS, 0, nullptr, 0, pointer_size, 0,
189ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky                         is64bit ? Patch<Elf_Addr, uint64_t, kAbsoluteAddress> :
190ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky                                   Patch<Elf_Addr, uint32_t, kAbsoluteAddress>,
191ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky                         text);
192033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
193033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                        Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text);
194033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
195033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0);
196033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky  RawSection debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0,
197033d745bb9412c9b546d29395cc9efbbb4fa306eDavid Srbecky                        Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text);
198bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  if (!oat_writer->GetMethodDebugInfo().empty()) {
199bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    if (compiler_driver_->GetCompilerOptions().GetIncludeCFI()) {
200ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky      if (kCFIFormat == dwarf::DW_EH_FRAME_FORMAT) {
201ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        dwarf::WriteCFISection(
202ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            compiler_driver_, oat_writer,
203ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            dwarf::DW_EH_PE_pcrel, kCFIFormat,
204ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            eh_frame.GetBuffer(), eh_frame.GetPatchLocations(),
205ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            eh_frame_hdr.GetBuffer(), eh_frame_hdr.GetPatchLocations());
206ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        builder->RegisterSection(&eh_frame);
207ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        builder->RegisterSection(&eh_frame_hdr);
208ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky      } else {
209ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        DCHECK(kCFIFormat == dwarf::DW_DEBUG_FRAME_FORMAT);
210ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        dwarf::WriteCFISection(
211ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            compiler_driver_, oat_writer,
212ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            dwarf::DW_EH_PE_absptr, kCFIFormat,
213ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            debug_frame.GetBuffer(), debug_frame.GetPatchLocations(),
214ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            nullptr, nullptr);
215ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        builder->RegisterSection(&debug_frame);
216ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky        *oat_writer->GetAbsolutePatchLocationsFor(".debug_frame") =
217ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky            *debug_frame.GetPatchLocations();
218ad5fa8c5b26a325dc2a9521b87188755046c17f3David Srbecky      }
219bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    }
220bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
221bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      // Add methods to .symtab.
222bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      WriteDebugSymbols(builder.get(), oat_writer);
223bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      // Generate DWARF .debug_* sections.
224bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      dwarf::WriteDebugSections(
225bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          compiler_driver_, oat_writer,
226bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          debug_info.GetBuffer(), debug_info.GetPatchLocations(),
227bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          debug_abbrev.GetBuffer(),
228bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          debug_str.GetBuffer(),
229bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          debug_line.GetBuffer(), debug_line.GetPatchLocations());
230bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      builder->RegisterSection(&debug_info);
231bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      builder->RegisterSection(&debug_abbrev);
232bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      builder->RegisterSection(&debug_str);
233bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      builder->RegisterSection(&debug_line);
234bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      *oat_writer->GetAbsolutePatchLocationsFor(".debug_info") =
235bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          *debug_info.GetPatchLocations();
236bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky      *oat_writer->GetAbsolutePatchLocationsFor(".debug_line") =
237bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky          *debug_line.GetPatchLocations();
238bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    }
2396a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom  }
2406a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom
241bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  // Add relocation section.
242bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  RawSection oat_patches(".oat_patches", SHT_OAT_PATCH, 0, nullptr, 0, 1, 0);
2432f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky  if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation() ||
2442f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      // ElfWriter::Fixup will be called regardless and it needs to be able
2452f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      // to patch debug sections so we have to include patches for them.
2462f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky      compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
2472f6cdb01f74772c1c521a125776ef57ea3c73d43David Srbecky    EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(), oat_patches.GetBuffer());
248bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    builder->RegisterSection(&oat_patches);
24953cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light  }
25053cb16b98acf3cf6f3a1e2204ad4958ecf1b5a3cAlex Light
251bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  return builder->Write(elf_file_);
252b12f34742be4adaa804cc0d388ba51603bb95955Brian Carlstrom}
253ae9fd93c39a341e2dffe15c61cc7d9e841fa92c4Mark Mendell
254533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate <typename ElfTypes>
255533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckystatic void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer) {
2563b9d57ab580a0593635a7dbe3dd2e2c76274f9faDavid Srbecky  const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo();
257388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky  bool generated_mapping_symbol = false;
258626a1666015b0fa201e979870baf06afa93b65e7David Srbecky
259626a1666015b0fa201e979870baf06afa93b65e7David Srbecky  // Find all addresses (low_pc) which contain deduped methods.
260626a1666015b0fa201e979870baf06afa93b65e7David Srbecky  // The first instance of method is not marked deduped_, but the rest is.
261626a1666015b0fa201e979870baf06afa93b65e7David Srbecky  std::unordered_set<uint32_t> deduped_addresses;
262626a1666015b0fa201e979870baf06afa93b65e7David Srbecky  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
263626a1666015b0fa201e979870baf06afa93b65e7David Srbecky    if (it->deduped_) {
264626a1666015b0fa201e979870baf06afa93b65e7David Srbecky      deduped_addresses.insert(it->low_pc_);
265626a1666015b0fa201e979870baf06afa93b65e7David Srbecky    }
266626a1666015b0fa201e979870baf06afa93b65e7David Srbecky  }
267626a1666015b0fa201e979870baf06afa93b65e7David Srbecky
268bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky  auto* symtab = builder->GetSymtab();
26954fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  for (auto it = method_info.begin(); it != method_info.end(); ++it) {
2706d73c9d06bc0fc6b32825ca0a8224010933a026eDavid Srbecky    if (it->deduped_) {
2716d73c9d06bc0fc6b32825ca0a8224010933a026eDavid Srbecky      continue;  // Add symbol only for the first instance.
2726d73c9d06bc0fc6b32825ca0a8224010933a026eDavid Srbecky    }
2730df9e1faed9b095b084c4eca6ee59d24fba21c9fDavid Srbecky    std::string name = PrettyMethod(it->dex_method_index_, *it->dex_file_, true);
274626a1666015b0fa201e979870baf06afa93b65e7David Srbecky    if (deduped_addresses.find(it->low_pc_) != deduped_addresses.end()) {
275626a1666015b0fa201e979870baf06afa93b65e7David Srbecky      name += " [DEDUPED]";
2760df9e1faed9b095b084c4eca6ee59d24fba21c9fDavid Srbecky    }
2770df9e1faed9b095b084c4eca6ee59d24fba21c9fDavid Srbecky
2786f7158927fee233255f8e96719c374694b10cad3David Srbecky    uint32_t low_pc = it->low_pc_;
2796f7158927fee233255f8e96719c374694b10cad3David Srbecky    // Add in code delta, e.g., thumb bit 0 for Thumb2 code.
2806f7158927fee233255f8e96719c374694b10cad3David Srbecky    low_pc += it->compiled_method_->CodeDelta();
281bc90fd09e09a845ae6ea0d84ad67560575a94142David Srbecky    symtab->AddSymbol(name, builder->GetText(), low_pc,
2826f7158927fee233255f8e96719c374694b10cad3David Srbecky                      true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC);
28354fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
284f9734550c1453f173150b12efc72b10ebf67878dNingsheng Jian    // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2
285f9734550c1453f173150b12efc72b10ebf67878dNingsheng Jian    // instructions, so that disassembler tools can correctly disassemble.
286388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky    // Note that even if we generate just a single mapping symbol, ARM's Streamline
287388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky    // requires it to match function symbol.  Just address 0 does not work.
288f9734550c1453f173150b12efc72b10ebf67878dNingsheng Jian    if (it->compiled_method_->GetInstructionSet() == kThumb2) {
289388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky      if (!generated_mapping_symbol || !kGenerateSingleArmMappingSymbol) {
290388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky        symtab->AddSymbol("$t", builder->GetText(), it->low_pc_ & ~1, true,
291388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky                          0, STB_LOCAL, STT_NOTYPE);
292388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky        generated_mapping_symbol = true;
293388d2861ce185fe9bbf1989f1467031467bd1de7David Srbecky      }
294f9734550c1453f173150b12efc72b10ebf67878dNingsheng Jian    }
29554fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe  }
29654fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe}
29754fc26c7350beb782d042ba61cb06284b3a367e4Andreas Gampe
298f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray// Explicit instantiations
299533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate class ElfWriterQuick<ElfTypes32>;
300533c207f9d2da6d913c4b10f6f757fe9d6367b10David Srbeckytemplate class ElfWriterQuick<ElfTypes64>;
301f9b87b1eece0e03578c4d1b627f1d5e8691a539aNicolas Geoffray
3026a47b9dc850b903aabefcfab4adb132cb68bba2eBrian Carlstrom}  // namespace art
303