1c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky/* 2c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * Copyright (C) 2016 The Android Open Source Project 3c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * 4c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * Licensed under the Apache License, Version 2.0 (the "License"); 5c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * you may not use this file except in compliance with the License. 6c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * You may obtain a copy of the License at 7c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * 8c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * http://www.apache.org/licenses/LICENSE-2.0 9c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * 10c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * Unless required by applicable law or agreed to in writing, software 11c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * distributed under the License is distributed on an "AS IS" BASIS, 12c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * See the License for the specific language governing permissions and 14c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky * limitations under the License. 15c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky */ 16c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 17c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "elf_debug_writer.h" 18c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 19c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include <vector> 2056da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky#include <unordered_map> 21c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 22d9c90373d640a5e08072cf469c372e24a8c0fc35David Brazdil#include "base/array_ref.h" 23c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/dwarf/dwarf_constants.h" 24c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_compilation_unit.h" 25c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_frame_writer.h" 26c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_info_writer.h" 27c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_line_writer.h" 28c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_debug_loc_writer.h" 29c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_gnu_debugdata_writer.h" 30c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/elf_symtab_writer.h" 31c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "debug/method_debug_info.h" 327452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko#include "linker/elf_builder.h" 33c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky#include "linker/vector_output_stream.h" 34d49012909625c3bf87bf51138fe79315ce1b1bdcAndreas Gampe#include "oat.h" 35c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 36c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckynamespace art { 37c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckynamespace debug { 38c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 39c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckytemplate <typename ElfTypes> 407452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Markovoid WriteDebugInfo(linker::ElfBuilder<ElfTypes>* builder, 4132210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky const DebugInfo& debug_info, 42c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky dwarf::CFIFormat cfi_format, 43c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky bool write_oat_patches) { 4409c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky // Write .strtab and .symtab. 4532210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky WriteDebugSymbols(builder, false /* mini-debug-info */, debug_info); 4609c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky 4709c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky // Write .debug_frame. 4832210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky WriteCFISection(builder, debug_info.compiled_methods, cfi_format, write_oat_patches); 49c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 5056da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // Group the methods into compilation units based on class. 5156da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky std::unordered_map<const DexFile::ClassDef*, ElfCompilationUnit> class_to_compilation_unit; 5232210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky for (const MethodDebugInfo& mi : debug_info.compiled_methods) { 5309c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky if (mi.dex_file != nullptr) { 5409c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky auto& dex_class_def = mi.dex_file->GetClassDef(mi.class_def_index); 5556da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky ElfCompilationUnit& cu = class_to_compilation_unit[&dex_class_def]; 5609c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky cu.methods.push_back(&mi); 5709c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky // All methods must have the same addressing mode otherwise the min/max below does not work. 5809c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky DCHECK_EQ(cu.methods.front()->is_code_address_text_relative, mi.is_code_address_text_relative); 5909c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky cu.is_code_address_text_relative = mi.is_code_address_text_relative; 6009c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky cu.code_address = std::min(cu.code_address, mi.code_address); 6109c2a6be63337ee060e2d54bd01cf18be7301d29David Srbecky cu.code_end = std::max(cu.code_end, mi.code_address + mi.code_size); 62c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 63c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 64c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 6556da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // Sort compilation units to make the compiler output deterministic. 6656da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky std::vector<ElfCompilationUnit> compilation_units; 6756da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky compilation_units.reserve(class_to_compilation_unit.size()); 6856da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky for (auto& it : class_to_compilation_unit) { 6956da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // The .debug_line section requires the methods to be sorted by code address. 7056da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky std::stable_sort(it.second.methods.begin(), 7156da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky it.second.methods.end(), 7256da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky [](const MethodDebugInfo* a, const MethodDebugInfo* b) { 7356da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky return a->code_address < b->code_address; 7456da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky }); 7556da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky compilation_units.push_back(std::move(it.second)); 7656da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky } 7756da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky std::sort(compilation_units.begin(), 7856da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky compilation_units.end(), 7956da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky [](ElfCompilationUnit& a, ElfCompilationUnit& b) { 8056da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // Sort by index of the first method within the method_infos array. 8156da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // This assumes that the order of method_infos is deterministic. 8256da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky // Code address is not good for sorting due to possible duplicates. 8356da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky return a.methods.front() < b.methods.front(); 8456da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky }); 8556da23c6a20e01724b9495443ccab75d4abcaa36David Srbecky 86c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky // Write .debug_line section. 87c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky if (!compilation_units.empty()) { 88c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky ElfDebugLineWriter<ElfTypes> line_writer(builder); 89c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky line_writer.Start(); 90c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky for (auto& compilation_unit : compilation_units) { 91c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky line_writer.WriteCompilationUnit(compilation_unit); 92c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 93c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky line_writer.End(write_oat_patches); 94c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 95c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 96c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky // Write .debug_info section. 97c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky if (!compilation_units.empty()) { 98c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky ElfDebugInfoWriter<ElfTypes> info_writer(builder); 99c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky info_writer.Start(); 100c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky for (const auto& compilation_unit : compilation_units) { 101c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer); 102c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky cu_writer.Write(compilation_unit); 103c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 104c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky info_writer.End(write_oat_patches); 105c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 106c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 107c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 108c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckystd::vector<uint8_t> MakeMiniDebugInfo( 109c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky InstructionSet isa, 1105d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 11132210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky uint64_t text_section_address, 11232210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky size_t text_section_size, 11332210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky uint64_t dex_section_address, 11432210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky size_t dex_section_size, 11532210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky const DebugInfo& debug_info) { 116c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky if (Is64BitInstructionSet(isa)) { 1175d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return MakeMiniDebugInfoInternal<ElfTypes64>(isa, 1185d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky features, 11932210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky text_section_address, 12032210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky text_section_size, 12132210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky dex_section_address, 12232210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky dex_section_size, 12332210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky debug_info); 124c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } else { 1255d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return MakeMiniDebugInfoInternal<ElfTypes32>(isa, 1265d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky features, 12732210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky text_section_address, 12832210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky text_section_size, 12932210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky dex_section_address, 13032210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky dex_section_size, 13132210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky debug_info); 132c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 133c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 134c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 135c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckytemplate <typename ElfTypes> 136f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbeckystatic std::vector<uint8_t> MakeElfFileForJITInternal( 137fe736b775c7774bb2f7072e022099ca47dd21a3cDavid Srbecky InstructionSet isa, 1385d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 139f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky bool mini_debug_info, 140c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky ArrayRef<const MethodDebugInfo> method_infos) { 141c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky CHECK_GT(method_infos.size(), 0u); 142c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky uint64_t min_address = std::numeric_limits<uint64_t>::max(); 143c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky uint64_t max_address = 0; 144c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky for (const MethodDebugInfo& mi : method_infos) { 145c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky CHECK_EQ(mi.is_code_address_text_relative, false); 146c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky min_address = std::min(min_address, mi.code_address); 147c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky max_address = std::max(max_address, mi.code_address + mi.code_size); 148c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky } 14932210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky DebugInfo debug_info{}; 150c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky debug_info.compiled_methods = method_infos; 151c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky std::vector<uint8_t> buffer; 152c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky buffer.reserve(KB); 1537452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko linker::VectorOutputStream out("Debug ELF file", &buffer); 1547452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder( 1557452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko new linker::ElfBuilder<ElfTypes>(isa, features, &out)); 156c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky // No program headers since the ELF file is not linked and has no allocated sections. 157c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky builder->Start(false /* write_program_headers */); 158f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky if (mini_debug_info) { 159ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky if (method_infos.size() > 1) { 160ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky std::vector<uint8_t> mdi = MakeMiniDebugInfo(isa, 161ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky features, 162ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky min_address, 163ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky max_address - min_address, 164ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky /* dex_section_address */ 0, 165ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky /* dex_section_size */ 0, 166ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky debug_info); 167ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky builder->WriteSection(".gnu_debugdata", &mdi); 168ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky } else { 169ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky // The compression is great help for multiple methods but it is not worth it for a 170ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky // single method due to the overheads so skip the compression here for performance. 171ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address); 172ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky WriteDebugSymbols(builder.get(), true /* mini-debug-info */, debug_info); 173ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky WriteCFISection(builder.get(), 174ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky debug_info.compiled_methods, 175ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky dwarf::DW_DEBUG_FRAME_FORMAT, 176ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky false /* write_oat_paches */); 177ec419db26d96c74e2cb2418db247f9a94ff0d262David Srbecky } 178f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky } else { 179c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky builder->GetText()->AllocateVirtualMemory(min_address, max_address - min_address); 180f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky WriteDebugInfo(builder.get(), 18132210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky debug_info, 182f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky dwarf::DW_DEBUG_FRAME_FORMAT, 183f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky false /* write_oat_patches */); 184f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky } 185c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky builder->End(); 186c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky CHECK(builder->Good()); 18793205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Marko return buffer; 188c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 189c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 190f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbeckystd::vector<uint8_t> MakeElfFileForJIT( 191fe736b775c7774bb2f7072e022099ca47dd21a3cDavid Srbecky InstructionSet isa, 192fe736b775c7774bb2f7072e022099ca47dd21a3cDavid Srbecky const InstructionSetFeatures* features, 193f4886df5e72fa21eddfc4cc7860f4154929b3380David Srbecky bool mini_debug_info, 194c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky ArrayRef<const MethodDebugInfo> method_infos) { 195c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky if (Is64BitInstructionSet(isa)) { 196c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky return MakeElfFileForJITInternal<ElfTypes64>(isa, features, mini_debug_info, method_infos); 197c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } else { 198c684f337eae6bd3d77fa44cb568d2bab113e4ceeDavid Srbecky return MakeElfFileForJITInternal<ElfTypes32>(isa, features, mini_debug_info, method_infos); 199c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 200c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 201c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 202c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckytemplate <typename ElfTypes> 20393205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Markostatic std::vector<uint8_t> WriteDebugElfFileForClassesInternal( 204fe736b775c7774bb2f7072e022099ca47dd21a3cDavid Srbecky InstructionSet isa, 2055d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const InstructionSetFeatures* features, 2065d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky const ArrayRef<mirror::Class*>& types) 207bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 208c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky std::vector<uint8_t> buffer; 209c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky buffer.reserve(KB); 2107452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko linker::VectorOutputStream out("Debug ELF file", &buffer); 2117452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko std::unique_ptr<linker::ElfBuilder<ElfTypes>> builder( 2127452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko new linker::ElfBuilder<ElfTypes>(isa, features, &out)); 213c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky // No program headers since the ELF file is not linked and has no allocated sections. 214c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky builder->Start(false /* write_program_headers */); 215c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky ElfDebugInfoWriter<ElfTypes> info_writer(builder.get()); 216c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky info_writer.Start(); 217c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky ElfCompilationUnitWriter<ElfTypes> cu_writer(&info_writer); 218c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky cu_writer.Write(types); 219c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky info_writer.End(false /* write_oat_patches */); 220c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 221c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky builder->End(); 222c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky CHECK(builder->Good()); 22393205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Marko return buffer; 224c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 225c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 22693205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Markostd::vector<uint8_t> WriteDebugElfFileForClasses(InstructionSet isa, 22793205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Marko const InstructionSetFeatures* features, 22893205e395f777c1dd81d3f164cf9a4aec4bde45fVladimir Marko const ArrayRef<mirror::Class*>& types) { 229c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky if (Is64BitInstructionSet(isa)) { 2305d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return WriteDebugElfFileForClassesInternal<ElfTypes64>(isa, features, types); 231c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } else { 2325d8112029d0e085c5a0099257daa4c7e29c12310David Srbecky return WriteDebugElfFileForClassesInternal<ElfTypes32>(isa, features, types); 233c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky } 234c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} 235c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 236c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky// Explicit instantiations 237c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckytemplate void WriteDebugInfo<ElfTypes32>( 2387452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko linker::ElfBuilder<ElfTypes32>* builder, 23932210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky const DebugInfo& debug_info, 240c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky dwarf::CFIFormat cfi_format, 241c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky bool write_oat_patches); 242c5bfa97c47d656b76f297af8abcd5f7502987399David Srbeckytemplate void WriteDebugInfo<ElfTypes64>( 2437452797678c4345d4a9e65b03e00af703c2c5fe0Vladimir Marko linker::ElfBuilder<ElfTypes64>* builder, 24432210b9f8c30e202e275764200315fe26f22f34cDavid Srbecky const DebugInfo& debug_info, 245c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky dwarf::CFIFormat cfi_format, 246c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky bool write_oat_patches); 247c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky 248c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} // namespace debug 249c5bfa97c47d656b76f297af8abcd5f7502987399David Srbecky} // namespace art 250