elf_writer_quick.cc revision 527c9c71f0c6e2f9943ac028e7c050500699a44b
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 "buffered_output_stream.h" 25#include "compiled_method.h" 26#include "dex_file-inl.h" 27#include "driver/compiler_driver.h" 28#include "driver/compiler_options.h" 29#include "elf_builder.h" 30#include "elf_file.h" 31#include "elf_utils.h" 32#include "elf_writer_debug.h" 33#include "file_output_stream.h" 34#include "globals.h" 35#include "leb128.h" 36#include "oat.h" 37#include "oat_writer.h" 38#include "utils.h" 39 40namespace art { 41 42template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 43 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 44 typename Elf_Phdr, typename Elf_Shdr> 45bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 46 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Create(File* elf_file, 47 OatWriter* oat_writer, 48 const std::vector<const DexFile*>& dex_files, 49 const std::string& android_root, 50 bool is_host, 51 const CompilerDriver& driver) { 52 ElfWriterQuick elf_writer(driver, elf_file); 53 return elf_writer.Write(oat_writer, dex_files, android_root, is_host); 54} 55 56class OatWriterWrapper FINAL : public CodeOutput { 57 public: 58 explicit OatWriterWrapper(OatWriter* oat_writer) : oat_writer_(oat_writer) {} 59 60 void SetCodeOffset(size_t offset) { 61 oat_writer_->SetOatDataOffset(offset); 62 } 63 bool Write(OutputStream* out) OVERRIDE { 64 return oat_writer_->Write(out); 65 } 66 private: 67 OatWriter* const oat_writer_; 68}; 69 70template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 71 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 72 typename Elf_Phdr, typename Elf_Shdr> 73static void WriteDebugSymbols(ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 74 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder, 75 OatWriter* oat_writer); 76 77// Encode patch locations in .oat_patches format. 78template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 79 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 80 typename Elf_Phdr, typename Elf_Shdr> 81void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, Elf_Sym, Elf_Ehdr, 82 Elf_Phdr, Elf_Shdr>::EncodeOatPatches(const OatWriter::PatchLocationsMap& sections, 83 std::vector<uint8_t>* buffer) { 84 for (const auto& section : sections) { 85 const std::string& name = section.first; 86 std::vector<uintptr_t>* locations = section.second.get(); 87 DCHECK(!name.empty()); 88 std::sort(locations->begin(), locations->end()); 89 // Reserve buffer space - guess 2 bytes per ULEB128. 90 buffer->reserve(buffer->size() + name.size() + locations->size() * 2); 91 // Write null-terminated section name. 92 const uint8_t* name_data = reinterpret_cast<const uint8_t*>(name.c_str()); 93 buffer->insert(buffer->end(), name_data, name_data + name.size() + 1); 94 // Write placeholder for data length. 95 size_t length_pos = buffer->size(); 96 EncodeUnsignedLeb128(buffer, UINT32_MAX); 97 // Write LEB128 encoded list of advances (deltas between consequtive addresses). 98 size_t data_pos = buffer->size(); 99 uintptr_t address = 0; // relative to start of section. 100 for (uintptr_t location : *locations) { 101 DCHECK_LT(location - address, UINT32_MAX) << "Large gap between patch locations"; 102 EncodeUnsignedLeb128(buffer, location - address); 103 address = location; 104 } 105 // Update length. 106 UpdateUnsignedLeb128(buffer->data() + length_pos, buffer->size() - data_pos); 107 } 108 buffer->push_back(0); // End of sections. 109} 110 111template<typename AddressType, bool SubtractPatchLocation = false> 112static void PatchAddresses(const std::vector<uintptr_t>* patch_locations, 113 AddressType delta, std::vector<uint8_t>* buffer) { 114 // Addresses in .debug_* sections are unaligned. 115 typedef __attribute__((__aligned__(1))) AddressType UnalignedAddressType; 116 if (patch_locations != nullptr) { 117 for (uintptr_t patch_location : *patch_locations) { 118 *reinterpret_cast<UnalignedAddressType*>(buffer->data() + patch_location) += 119 delta - (SubtractPatchLocation ? patch_location : 0); 120 } 121 } 122} 123 124template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 125 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 126 typename Elf_Phdr, typename Elf_Shdr> 127bool ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 128 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>::Write(OatWriter* oat_writer, 129 const std::vector<const DexFile*>& dex_files_unused ATTRIBUTE_UNUSED, 130 const std::string& android_root_unused ATTRIBUTE_UNUSED, 131 bool is_host_unused ATTRIBUTE_UNUSED) { 132 constexpr bool debug = false; 133 const OatHeader& oat_header = oat_writer->GetOatHeader(); 134 Elf_Word oat_data_size = oat_header.GetExecutableOffset(); 135 uint32_t oat_exec_size = oat_writer->GetSize() - oat_data_size; 136 uint32_t oat_bss_size = oat_writer->GetBssSize(); 137 138 OatWriterWrapper wrapper(oat_writer); 139 140 std::unique_ptr<ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 141 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr> > builder( 142 new ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 143 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>( 144 &wrapper, 145 elf_file_, 146 compiler_driver_->GetInstructionSet(), 147 0, 148 oat_data_size, 149 oat_data_size, 150 oat_exec_size, 151 RoundUp(oat_data_size + oat_exec_size, kPageSize), 152 oat_bss_size, 153 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols(), 154 debug)); 155 156 InstructionSet isa = compiler_driver_->GetInstructionSet(); 157 int alignment = GetInstructionSetPointerSize(isa); 158 typedef ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> RawSection; 159 RawSection eh_frame(".eh_frame", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, alignment, 0); 160 RawSection eh_frame_hdr(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC, nullptr, 0, 4, 0); 161 RawSection debug_info(".debug_info", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 162 RawSection debug_abbrev(".debug_abbrev", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 163 RawSection debug_str(".debug_str", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 164 RawSection debug_line(".debug_line", SHT_PROGBITS, 0, nullptr, 0, 1, 0); 165 RawSection oat_patches(".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, 1, 0); 166 167 // Do not add to .oat_patches since we will make the addresses relative. 168 std::vector<uintptr_t> eh_frame_patches; 169 if (compiler_driver_->GetCompilerOptions().GetIncludeCFI() && 170 !oat_writer->GetMethodDebugInfo().empty()) { 171 dwarf::WriteEhFrame(compiler_driver_, oat_writer, 172 dwarf::DW_EH_PE_pcrel, 173 eh_frame.GetBuffer(), &eh_frame_patches, 174 eh_frame_hdr.GetBuffer()); 175 builder->RegisterRawSection(&eh_frame); 176 builder->RegisterRawSection(&eh_frame_hdr); 177 } 178 179 // Must be done after .eh_frame is created since it is used in the Elf layout. 180 if (!builder->Init()) { 181 return false; 182 } 183 184 std::vector<uintptr_t>* debug_info_patches = nullptr; 185 std::vector<uintptr_t>* debug_line_patches = nullptr; 186 if (compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols() && 187 !oat_writer->GetMethodDebugInfo().empty()) { 188 // Add methods to .symtab. 189 WriteDebugSymbols(builder.get(), oat_writer); 190 // Generate DWARF .debug_* sections. 191 debug_info_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_info"); 192 debug_line_patches = oat_writer->GetAbsolutePatchLocationsFor(".debug_line"); 193 dwarf::WriteDebugSections(compiler_driver_, oat_writer, 194 debug_info.GetBuffer(), debug_info_patches, 195 debug_abbrev.GetBuffer(), 196 debug_str.GetBuffer(), 197 debug_line.GetBuffer(), debug_line_patches); 198 builder->RegisterRawSection(&debug_info); 199 builder->RegisterRawSection(&debug_abbrev); 200 builder->RegisterRawSection(&debug_str); 201 builder->RegisterRawSection(&debug_line); 202 } 203 204 if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation() || 205 // ElfWriter::Fixup will be called regardless and it needs to be able 206 // to patch debug sections so we have to include patches for them. 207 compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) { 208 EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(), oat_patches.GetBuffer()); 209 builder->RegisterRawSection(&oat_patches); 210 } 211 212 // We know where .text and .eh_frame will be located, so patch the addresses. 213 Elf_Addr text_addr = builder->GetTextBuilder().GetSection()->sh_addr; 214 // TODO: Simplify once we use Elf64 - we can use Elf_Addr instead of branching. 215 if (Is64BitInstructionSet(compiler_driver_->GetInstructionSet())) { 216 // relative_address = (text_addr + address) - (eh_frame_addr + patch_location); 217 PatchAddresses<uint64_t, true>(&eh_frame_patches, 218 text_addr - eh_frame.GetSection()->sh_addr, eh_frame.GetBuffer()); 219 PatchAddresses<uint64_t>(debug_info_patches, text_addr, debug_info.GetBuffer()); 220 PatchAddresses<uint64_t>(debug_line_patches, text_addr, debug_line.GetBuffer()); 221 } else { 222 // relative_address = (text_addr + address) - (eh_frame_addr + patch_location); 223 PatchAddresses<uint32_t, true>(&eh_frame_patches, 224 text_addr - eh_frame.GetSection()->sh_addr, eh_frame.GetBuffer()); 225 PatchAddresses<uint32_t>(debug_info_patches, text_addr, debug_info.GetBuffer()); 226 PatchAddresses<uint32_t>(debug_line_patches, text_addr, debug_line.GetBuffer()); 227 } 228 229 return builder->Write(); 230} 231 232template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr, 233 typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr, 234 typename Elf_Phdr, typename Elf_Shdr> 235// Do not inline to avoid Clang stack frame problems. b/18738594 236NO_INLINE 237static void WriteDebugSymbols(ElfBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, 238 Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder, 239 OatWriter* oat_writer) { 240 const std::vector<OatWriter::DebugInfo>& method_info = oat_writer->GetMethodDebugInfo(); 241 242 // Find all addresses (low_pc) which contain deduped methods. 243 // The first instance of method is not marked deduped_, but the rest is. 244 std::unordered_set<uint32_t> deduped_addresses; 245 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 246 if (it->deduped_) { 247 deduped_addresses.insert(it->low_pc_); 248 } 249 } 250 251 ElfSymtabBuilder<Elf_Word, Elf_Sword, Elf_Addr, Elf_Sym, Elf_Shdr>* symtab = 252 builder->GetSymtabBuilder(); 253 for (auto it = method_info.begin(); it != method_info.end(); ++it) { 254 std::string name = PrettyMethod(it->dex_method_index_, *it->dex_file_, true); 255 if (deduped_addresses.find(it->low_pc_) != deduped_addresses.end()) { 256 name += " [DEDUPED]"; 257 } 258 259 uint32_t low_pc = it->low_pc_; 260 // Add in code delta, e.g., thumb bit 0 for Thumb2 code. 261 low_pc += it->compiled_method_->CodeDelta(); 262 symtab->AddSymbol(name, &builder->GetTextBuilder(), low_pc, 263 true, it->high_pc_ - it->low_pc_, STB_GLOBAL, STT_FUNC); 264 265 // Conforming to aaelf, add $t mapping symbol to indicate start of a sequence of thumb2 266 // instructions, so that disassembler tools can correctly disassemble. 267 if (it->compiled_method_->GetInstructionSet() == kThumb2) { 268 symtab->AddSymbol("$t", &builder->GetTextBuilder(), it->low_pc_ & ~1, true, 269 0, STB_LOCAL, STT_NOTYPE); 270 } 271 } 272} 273 274// Explicit instantiations 275template class ElfWriterQuick<Elf32_Word, Elf32_Sword, Elf32_Addr, Elf32_Dyn, 276 Elf32_Sym, Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr>; 277template class ElfWriterQuick<Elf64_Word, Elf64_Sword, Elf64_Addr, Elf64_Dyn, 278 Elf64_Sym, Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr>; 279 280} // namespace art 281