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