elf_writer_quick.cc revision ad5fa8c5b26a325dc2a9521b87188755046c17f3
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/logging.h" 23#include "base/unix_file/fd_file.h" 24#include "compiled_method.h" 25#include "dex_file-inl.h" 26#include "driver/compiler_driver.h" 27#include "driver/compiler_options.h" 28#include "elf_builder.h" 29#include "elf_file.h" 30#include "elf_utils.h" 31#include "elf_writer_debug.h" 32#include "globals.h" 33#include "leb128.h" 34#include "oat.h" 35#include "oat_writer.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. 46constexpr dwarf::CFIFormat kCFIFormat = dwarf::DW_EH_FRAME_FORMAT; 47 48template <typename ElfTypes> 49bool ElfWriterQuick<ElfTypes>::Create(File* elf_file, 50 OatWriter* oat_writer, 51 const std::vector<const DexFile*>& dex_files, 52 const std::string& android_root, 53 bool is_host, 54 const CompilerDriver& driver) { 55 ElfWriterQuick elf_writer(driver, elf_file); 56 return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 57} 58 59template <typename ElfTypes> 60static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer); 61 62// Encode patch locations in .oat_patches format. 63template <typename ElfTypes> 64void ElfWriterQuick<ElfTypes>::EncodeOatPatches( 65 const OatWriter::PatchLocationsMap& sections, 66 std::vector<uint8_t>* buffer) { 67 for (const auto& section : sections) { 68 const std::string& name = section.first; 69 std::vector<uintptr_t>* locations = section.second.get(); 70 DCHECK(!name.empty()); 71 std::sort(locations->begin(), locations->end()); 72 // Reserve buffer space - guess 2 bytes per ULEB128. 73 buffer->reserve(buffer->size() + name.size() + locations->size() * 2); 74 // Write null-terminated section name. 75 const uint8_t* name_data = reinterpret_cast<const uint8_t*>(name.c_str()); 76 buffer->insert(buffer->end(), name_data, name_data + name.size() + 1); 77 // Write placeholder for data length. 78 size_t length_pos = buffer->size(); 79 EncodeUnsignedLeb128(buffer, UINT32_MAX); 80 // Write LEB128 encoded list of advances (deltas between consequtive addresses). 81 size_t data_pos = buffer->size(); 82 uintptr_t address = 0; // relative to start of section. 83 for (uintptr_t location : *locations) { 84 DCHECK_LT(location - address, UINT32_MAX) << "Large gap between patch locations"; 85 EncodeUnsignedLeb128(buffer, location - address); 86 address = location; 87 } 88 // Update length. 89 UpdateUnsignedLeb128(buffer->data() + length_pos, buffer->size() - data_pos); 90 } 91 buffer->push_back(0); // End of sections. 92} 93 94class RodataWriter FINAL : public CodeOutput { 95 public: 96 explicit RodataWriter(OatWriter* oat_writer) : oat_writer_(oat_writer) {} 97 98 bool Write(OutputStream* out) OVERRIDE { 99 return oat_writer_->WriteRodata(out); 100 } 101 102 private: 103 OatWriter* oat_writer_; 104}; 105 106class TextWriter FINAL : public CodeOutput { 107 public: 108 explicit TextWriter(OatWriter* oat_writer) : oat_writer_(oat_writer) {} 109 110 bool Write(OutputStream* out) OVERRIDE { 111 return oat_writer_->WriteCode(out); 112 } 113 114 private: 115 OatWriter* oat_writer_; 116}; 117 118enum PatchResult { 119 kAbsoluteAddress, // Absolute memory location. 120 kPointerRelativeAddress, // Offset relative to the location of the pointer. 121 kSectionRelativeAddress, // Offset relative to start of containing section. 122}; 123 124// Patch memory addresses within a buffer. 125// It assumes that the unpatched addresses are offsets relative to base_address. 126// (which generally means method's low_pc relative to the start of .text) 127template <typename Elf_Addr, typename Address, PatchResult kPatchResult> 128static void Patch(const std::vector<uintptr_t>& patch_locations, 129 Elf_Addr buffer_address, Elf_Addr base_address, 130 std::vector<uint8_t>* buffer) { 131 for (uintptr_t location : patch_locations) { 132 typedef __attribute__((__aligned__(1))) Address UnalignedAddress; 133 auto* to_patch = reinterpret_cast<UnalignedAddress*>(buffer->data() + location); 134 switch (kPatchResult) { 135 case kAbsoluteAddress: 136 *to_patch = (base_address + *to_patch); 137 break; 138 case kPointerRelativeAddress: 139 *to_patch = (base_address + *to_patch) - (buffer_address + location); 140 break; 141 case kSectionRelativeAddress: 142 *to_patch = (base_address + *to_patch) - buffer_address; 143 break; 144 } 145 } 146} 147 148template <typename ElfTypes> 149bool ElfWriterQuick<ElfTypes>::Write( 150 OatWriter* oat_writer, 151 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED, 152 const std::string& android_root_unused ATTRIBUTE_UNUSED, 153 bool is_host_unused ATTRIBUTE_UNUSED) { 154 using Elf_Addr = typename ElfTypes::Addr; 155 const InstructionSet isa = compiler_driver_->GetInstructionSet(); 156 157 // Setup the builder with the main OAT sections (.rodata .text .bss). 158 const size_t rodata_size = oat_writer->GetOatHeader().GetExecutableOffset(); 159 const size_t text_size = oat_writer->GetSize() - rodata_size; 160 const size_t bss_size = oat_writer->GetBssSize(); 161 RodataWriter rodata_writer(oat_writer); 162 TextWriter text_writer(oat_writer); 163 std::unique_ptr<ElfBuilder<ElfTypes>> builder(new ElfBuilder<ElfTypes>( 164 isa, rodata_size, &rodata_writer, text_size, &text_writer, bss_size)); 165 166 // Add debug sections. 167 // They are stack allocated here (in the same scope as the builder), 168 // but they are registred with the builder only if they are used. 169 using RawSection = typename ElfBuilder<ElfTypes>::RawSection; 170 const auto* text = builder->GetText(); 171 const bool is64bit = Is64BitInstructionSet(isa); 172 const int pointer_size = GetInstructionSetPointerSize(isa); 173 RawSection eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, kPageSize, 0, 174 is64bit ? Patch<Elf_Addr, uint64_t, kPointerRelativeAddress> : 175 Patch<Elf_Addr, uint32_t, kPointerRelativeAddress>, 176 text); 177 RawSection eh_frame_hdr(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0, 178 Patch<Elf_Addr, uint32_t, kSectionRelativeAddress>, text); 179 RawSection debug_frame(".debug_frame", SHT_PROGBITS, 0, nullptr, 0, pointer_size, 0, 180 is64bit ? Patch<Elf_Addr, uint64_t, kAbsoluteAddress> : 181 Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, 182 text); 183 RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0, 184 Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text); 185 RawSection debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 186 RawSection debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 187 RawSection debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0, 188 Patch<Elf_Addr, uint32_t, kAbsoluteAddress>, text); 189 if (!oat_writer->GetMethodDebugInfo().empty()) { 190 if (compiler_driver_->GetCompilerOptions().GetIncludeCFI()) { 191 if (kCFIFormat == dwarf::DW_EH_FRAME_FORMAT) { 192 dwarf::WriteCFISection( 193 compiler_driver_, oat_writer, 194 dwarf::DW_EH_PE_pcrel, kCFIFormat, 195 eh_frame.GetBuffer(), eh_frame.GetPatchLocations(), 196 eh_frame_hdr.GetBuffer(), eh_frame_hdr.GetPatchLocations()); 197 builder->RegisterSection(&eh_frame); 198 builder->RegisterSection(&eh_frame_hdr); 199 } else { 200 DCHECK(kCFIFormat == dwarf::DW_DEBUG_FRAME_FORMAT); 201 dwarf::WriteCFISection( 202 compiler_driver_, oat_writer, 203 dwarf::DW_EH_PE_absptr, kCFIFormat, 204 debug_frame.GetBuffer(), debug_frame.GetPatchLocations(), 205 nullptr, nullptr); 206 builder->RegisterSection(&debug_frame); 207 *oat_writer->GetAbsolutePatchLocationsFor(".debug_frame") = 208 *debug_frame.GetPatchLocations(); 209 } 210 } 211 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { 212 // Add methods to .symtab. 213 WriteDebugSymbols(builder.get(), oat_writer); 214 // Generate DWARF .debug_* sections. 215 dwarf::WriteDebugSections( 216 compiler_driver_, oat_writer, 217 debug_info.GetBuffer(), debug_info.GetPatchLocations(), 218 debug_abbrev.GetBuffer(), 219 debug_str.GetBuffer(), 220 debug_line.GetBuffer(), debug_line.GetPatchLocations()); 221 builder->RegisterSection(&debug_info); 222 builder->RegisterSection(&debug_abbrev); 223 builder->RegisterSection(&debug_str); 224 builder->RegisterSection(&debug_line); 225 *oat_writer->GetAbsolutePatchLocationsFor(".debug_info") = 226 *debug_info.GetPatchLocations(); 227 *oat_writer->GetAbsolutePatchLocationsFor(".debug_line") = 228 *debug_line.GetPatchLocations(); 229 } 230 } 231 232 // Add relocation section. 233 RawSection oat_patches(".oat_patches", SHT_OAT_PATCH, 0, nullptr, 0, 1, 0); 234 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation() || 235 // ElfWriter::Fixup will be called regardless and it needs to be able 236 // to patch debug sections so we have to include patches for them. 237 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { 238 EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(), oat_patches.GetBuffer()); 239 builder->RegisterSection(&oat_patches); 240 } 241 242 return builder->Write(elf_file_); 243} 244 245template <typename ElfTypes> 246static void WriteDebugSymbols(ElfBuilder<ElfTypes>* builder, OatWriter* oat_writer) { 247 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo(); 248 249 // Find all addresses (low_pc) which contain deduped methods. 250 // The first instance of method is not marked deduped_, but the rest is. 251 std::unordered_set<uint32_t> deduped_addresses; 252 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 253 if (it->deduped_) { 254 deduped_addresses.insert(it->low_pc_); 255 } 256 } 257 258 auto* symtab = builder->GetSymtab(); 259 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 260 if (it->deduped_) { 261 continue; // Add symbol only for the first instance. 262 } 263 std::string name = PrettyMethod(it->dex_method_index_, *it->dex_file_, true); 264 if (deduped_addresses.find(it->low_pc_) != deduped_addresses.end()) { 265 name += " [DEDUPED]"; 266 } 267 268 uint32_t low_pc = it->low_pc_; 269 // Add in code delta, e.g., thumb bit 0 for Thumb2 code. 270 low_pc += it->compiled_method_->CodeDelta(); 271 symtab->AddSymbol(name, builder->GetText(), low_pc, 272 true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC); 273 274 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2 275 // instructions, so that disassembler tools can correctly disassemble. 276 if (it->compiled_method_->GetInstructionSet() == kThumb2) { 277 symtab->AddSymbol("$t", builder->GetText(), it->low_pc_ & ~1, true, 278 0, STB_LOCAL, STT_NOTYPE); 279 } 280 } 281} 282 283// Explicit instantiations 284template class ElfWriterQuick<ElfTypes32>; 285template class ElfWriterQuick<ElfTypes64>; 286 287} // namespace art 288