elf_writer_quick.cc revision e0febdfc2d9585d0d1b4a562b8e44d9058c71c37
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "elf_writer_quick.h" 18 19#include <unordered_map> 20#include <unordered_set> 21 22#include "base/casts.h" 23#include "base/logging.h" 24#include "base/stl_util.h" 25#include "compiled_method.h" 26#include "driver/compiler_options.h" 27#include "dwarf/method_debug_info.h" 28#include "elf.h" 29#include "elf_builder.h" 30#include "elf_utils.h" 31#include "elf_writer_debug.h" 32#include "globals.h" 33#include "leb128.h" 34#include "linker/buffered_output_stream.h" 35#include "linker/file_output_stream.h" 36#include "utils.h" 37 38namespace art { 39 40// .eh_frame and .debug_frame are almost identical. 41// Except for some minor formatting differences, the main difference 42// is that .eh_frame is allocated within the running program because 43// it is used by C++ exception handling (which we do not use so we 44// can choose either). C++ compilers generally tend to use .eh_frame 45// because if they need it sometimes, they might as well always use it. 46// Let's use .debug_frame because it is easier to strip or compress. 47constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_DEBUG_FRAME_FORMAT; 48 49template <typename ElfTypes> 50class ElfWriterQuick FINAL : public ElfWriter { 51 public: 52 ElfWriterQuick(InstructionSet instruction_set, 53 const CompilerOptions* compiler_options, 54 File* elf_file); 55 ~ElfWriterQuick(); 56 57 void Start() OVERRIDE; 58 OutputStream* StartRoData() OVERRIDE; 59 void EndRoData(OutputStream* rodata) OVERRIDE; 60 OutputStream* StartText() OVERRIDE; 61 void EndText(OutputStream* text) OVERRIDE; 62 void SetBssSize(size_t bss_size) OVERRIDE; 63 void WriteDynamicSection() OVERRIDE; 64 void WriteDebugInfo(const ArrayRef<const dwarf::MethodDebugInfo>& method_infos) OVERRIDE; 65 void WritePatchLocations(const ArrayRef<const uintptr_t>& patch_locations) OVERRIDE; 66 bool End() OVERRIDE; 67 68 virtual OutputStream* GetStream() OVERRIDE; 69 70 static void EncodeOatPatches(const std::vector<uintptr_t>& locations, 71 std::vector<uint8_t>* buffer); 72 73 private: 74 const CompilerOptions* const compiler_options_; 75 File* const elf_file_; 76 std::unique_ptr<BufferedOutputStream> output_stream_; 77 std::unique_ptr<ElfBuilder<ElfTypes>> builder_; 78 79 DISALLOW_IMPLICIT_CONSTRUCTORS(ElfWriterQuick); 80}; 81 82std::unique_ptr<ElfWriter> CreateElfWriterQuick(InstructionSet instruction_set, 83 const CompilerOptions* compiler_options, 84 File* elf_file) { 85 if (Is64BitInstructionSet(instruction_set)) { 86 return MakeUnique<ElfWriterQuick<ElfTypes64>>(instruction_set, compiler_options, elf_file); 87 } else { 88 return MakeUnique<ElfWriterQuick<ElfTypes32>>(instruction_set, compiler_options, elf_file); 89 } 90} 91 92template <typename ElfTypes> 93ElfWriterQuick<ElfTypes>::ElfWriterQuick(InstructionSet instruction_set, 94 const CompilerOptions* compiler_options, 95 File* elf_file) 96 : ElfWriter(), 97 compiler_options_(compiler_options), 98 elf_file_(elf_file), 99 output_stream_(MakeUnique<BufferedOutputStream>(MakeUnique<FileOutputStream>(elf_file))), 100 builder_(new ElfBuilder<ElfTypes>(instruction_set, output_stream_.get())) {} 101 102template <typename ElfTypes> 103ElfWriterQuick<ElfTypes>::~ElfWriterQuick() {} 104 105template <typename ElfTypes> 106void ElfWriterQuick<ElfTypes>::Start() { 107 builder_->Start(); 108} 109 110template <typename ElfTypes> 111OutputStream* ElfWriterQuick<ElfTypes>::StartRoData() { 112 auto* rodata = builder_->GetRoData(); 113 rodata->Start(); 114 return rodata; 115} 116 117template <typename ElfTypes> 118void ElfWriterQuick<ElfTypes>::EndRoData(OutputStream* rodata) { 119 CHECK_EQ(builder_->GetRoData(), rodata); 120 builder_->GetRoData()->End(); 121} 122 123template <typename ElfTypes> 124OutputStream* ElfWriterQuick<ElfTypes>::StartText() { 125 auto* text = builder_->GetText(); 126 text->Start(); 127 return text; 128} 129 130template <typename ElfTypes> 131void ElfWriterQuick<ElfTypes>::EndText(OutputStream* text) { 132 CHECK_EQ(builder_->GetText(), text); 133 builder_->GetText()->End(); 134} 135 136template <typename ElfTypes> 137void ElfWriterQuick<ElfTypes>::SetBssSize(size_t bss_size) { 138 auto* bss = builder_->GetBss(); 139 if (bss_size != 0u) { 140 bss->Start(); 141 bss->SetSize(bss_size); 142 bss->End(); 143 } 144} 145 146template <typename ElfTypes> 147void ElfWriterQuick<ElfTypes>::WriteDynamicSection() { 148 builder_->WriteDynamicSection(elf_file_->GetPath()); 149} 150 151template <typename ElfTypes> 152void ElfWriterQuick<ElfTypes>::WriteDebugInfo( 153 const ArrayRef<const dwarf::MethodDebugInfo>& method_infos) { 154 if (compiler_options_->GetGenerateDebugInfo()) { 155 dwarf::WriteDebugInfo(builder_.get(), method_infos, kCFIFormat); 156 } 157} 158 159template <typename ElfTypes> 160void ElfWriterQuick<ElfTypes>::WritePatchLocations( 161 const ArrayRef<const uintptr_t>& patch_locations) { 162 // Add relocation section for .text. 163 if (compiler_options_->GetIncludePatchInformation()) { 164 // Note that ElfWriter::Fixup will be called regardless and therefore 165 // we need to include oat_patches for debug sections unconditionally. 166 builder_->WritePatches(".text.oat_patches", patch_locations); 167 } 168} 169 170template <typename ElfTypes> 171bool ElfWriterQuick<ElfTypes>::End() { 172 builder_->End(); 173 174 return builder_->Good(); 175} 176 177template <typename ElfTypes> 178OutputStream* ElfWriterQuick<ElfTypes>::GetStream() { 179 return builder_->GetStream(); 180} 181 182// Explicit instantiations 183template class ElfWriterQuick<ElfTypes32>; 184template class ElfWriterQuick<ElfTypes64>; 185 186} // namespace art 187