Relocate DWARF using .oat_patches.

The current solution is to hard-code knowledge of DWARF in the linker.
This works for simple use of DWARF, but breaks as soon as I try to do
anything more complex.  Making the linker fully support DWARF would be
non-trivial task and would be essentially rewrite.  Using .oat_patches
is much easier solution.

Relocating .debug_* sections required extending .oat_patches to support
more sections than just .text.  I have encoded each section as
null-terminated section name followed by ULEB128 deltas.

The ULEB128 encoding shrinks .oat_patches for .text by factor of
about 6 with 64-bit compiler, and factor of 3 with 32-bit compiler.

On the other hand, it grows by the extra .oat_patches for DWARF which
were not present before (if debug symbols are included).

Overall, it is still a clear improvement even with the DWARF patches.

Change-Id: I78ffeda0f8a3da03341995a3b5ef15c954e16e9f
diff --git a/compiler/elf_writer_quick.cc b/compiler/elf_writer_quick.cc
index e9af25f..da1f81a 100644
--- a/compiler/elf_writer_quick.cc
+++ b/compiler/elf_writer_quick.cc
@@ -74,6 +74,40 @@
                                          Elf_Sym, Elf_Ehdr, Elf_Phdr, Elf_Shdr>* builder,
                               OatWriter* oat_writer);
 
+// Encode patch locations in .oat_patches format.
+template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
+          typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
+          typename Elf_Phdr, typename Elf_Shdr>
+void ElfWriterQuick<Elf_Word, Elf_Sword, Elf_Addr, Elf_Dyn, Elf_Sym, Elf_Ehdr,
+  Elf_Phdr, Elf_Shdr>::EncodeOatPatches(const OatWriter::PatchLocationsMap& sections,
+                                        std::vector<uint8_t>* buffer) {
+  for (const auto& section : sections) {
+    const std::string& name = section.first;
+    std::vector<uintptr_t>* locations = section.second.get();
+    DCHECK(!name.empty());
+    std::sort(locations->begin(), locations->end());
+    // Reserve buffer space - guess 2 bytes per ULEB128.
+    buffer->reserve(buffer->size() + name.size() + locations->size() * 2);
+    // Write null-terminated section name.
+    const uint8_t* name_data = reinterpret_cast<const uint8_t*>(name.c_str());
+    buffer->insert(buffer->end(), name_data, name_data + name.size() + 1);
+    // Write placeholder for data length.
+    size_t length_pos = buffer->size();
+    EncodeUnsignedLeb128(buffer, UINT32_MAX);
+    // Write LEB128 encoded list of advances (deltas between consequtive addresses).
+    size_t data_pos = buffer->size();
+    uintptr_t address = 0;  // relative to start of section.
+    for (uintptr_t location : *locations) {
+      DCHECK_LT(location - address, UINT32_MAX) << "Large gap between patch locations";
+      EncodeUnsignedLeb128(buffer, location - address);
+      address = location;
+    }
+    // Update length.
+    UpdateUnsignedLeb128(buffer->data() + length_pos, buffer->size() - data_pos);
+  }
+  buffer->push_back(0);  // End of sections.
+}
+
 template <typename Elf_Word, typename Elf_Sword, typename Elf_Addr,
           typename Elf_Dyn, typename Elf_Sym, typename Elf_Ehdr,
           typename Elf_Phdr, typename Elf_Shdr>
@@ -115,16 +149,13 @@
     WriteDebugSymbols(compiler_driver_, builder.get(), oat_writer);
   }
 
-  if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation()) {
+  if (compiler_driver_->GetCompilerOptions().GetIncludePatchInformation() ||
+      // ElfWriter::Fixup will be called regardless and it needs to be able
+      // to patch debug sections so we have to include patches for them.
+      compiler_driver_->GetCompilerOptions().GetIncludeDebugSymbols()) {
     ElfRawSectionBuilder<Elf_Word, Elf_Sword, Elf_Shdr> oat_patches(
-        ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, sizeof(uintptr_t), sizeof(uintptr_t));
-    const std::vector<uintptr_t>& locations = oat_writer->GetAbsolutePatchLocations();
-    const uint8_t* begin = reinterpret_cast<const uint8_t*>(&locations[0]);
-    const uint8_t* end = begin + locations.size() * sizeof(locations[0]);
-    oat_patches.GetBuffer()->assign(begin, end);
-    if (debug) {
-      LOG(INFO) << "Prepared .oat_patches for " << locations.size() << " patches.";
-    }
+        ".oat_patches", SHT_OAT_PATCH, 0, NULL, 0, 1, 0);
+    EncodeOatPatches(oat_writer->GetAbsolutePatchLocations(), oat_patches.GetBuffer());
     builder->RegisterRawSection(oat_patches);
   }