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