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