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_test.cc b/compiler/elf_writer_test.cc
index 8e2d175..3e5ad7b 100644
--- a/compiler/elf_writer_test.cc
+++ b/compiler/elf_writer_test.cc
@@ -19,6 +19,9 @@
 #include "base/stringprintf.h"
 #include "base/unix_file/fd_file.h"
 #include "common_compiler_test.h"
+#include "elf_file.h"
+#include "elf_file_impl.h"
+#include "elf_writer_quick.h"
 #include "oat.h"
 #include "utils.h"
 
@@ -85,4 +88,73 @@
   }
 }
 
+// Run only on host since we do unaligned memory accesses.
+#ifndef HAVE_ANDROID_OS
+
+static void PatchSection(const std::vector<uintptr_t>& patch_locations,
+                         std::vector<uint8_t>* section, int32_t delta) {
+  for (uintptr_t location : patch_locations) {
+    *reinterpret_cast<int32_t*>(section->data() + location) += delta;
+  }
+}
+
+TEST_F(ElfWriterTest, EncodeDecodeOatPatches) {
+  std::vector<uint8_t> oat_patches;  // Encoded patches.
+
+  // Encode patch locations for a few sections.
+  OatWriter::PatchLocationsMap sections;
+  std::vector<uintptr_t> patches0 { 0, 4, 8, 15, 128, 200 };  // NOLINT
+  sections.emplace(".section0", std::unique_ptr<std::vector<uintptr_t>>(
+      new std::vector<uintptr_t> { patches0 }));
+  std::vector<uintptr_t> patches1 { 8, 127 };  // NOLINT
+  sections.emplace(".section1", std::unique_ptr<std::vector<uintptr_t>>(
+      new std::vector<uintptr_t> { patches1 }));
+  std::vector<uintptr_t> patches2 { };  // NOLINT
+  sections.emplace(".section2", std::unique_ptr<std::vector<uintptr_t>>(
+      new std::vector<uintptr_t> { patches2 }));
+  ElfWriterQuick32::EncodeOatPatches(sections, &oat_patches);
+
+  // Create buffers to be patched.
+  std::vector<uint8_t> initial_data(256);
+  for (size_t i = 0; i < initial_data.size(); i++) {
+    initial_data[i] = i;
+  }
+  std::vector<uint8_t> section0_expected = initial_data;
+  std::vector<uint8_t> section1_expected = initial_data;
+  std::vector<uint8_t> section2_expected = initial_data;
+  std::vector<uint8_t> section0_actual = initial_data;
+  std::vector<uint8_t> section1_actual = initial_data;
+  std::vector<uint8_t> section2_actual = initial_data;
+
+  // Patch manually.
+  constexpr int32_t delta = 0x11235813;
+  PatchSection(patches0, &section0_expected, delta);
+  PatchSection(patches1, &section1_expected, delta);
+  PatchSection(patches2, &section2_expected, delta);
+
+  // Decode and apply patch locations.
+  bool section0_successful = ElfFileImpl32::ApplyOatPatches(
+      oat_patches.data(), oat_patches.data() + oat_patches.size(),
+      ".section0", delta,
+      section0_actual.data(), section0_actual.data() + section0_actual.size());
+  EXPECT_TRUE(section0_successful);
+  EXPECT_EQ(section0_expected, section0_actual);
+
+  bool section1_successful = ElfFileImpl32::ApplyOatPatches(
+      oat_patches.data(), oat_patches.data() + oat_patches.size(),
+      ".section1", delta,
+      section1_actual.data(), section1_actual.data() + section1_actual.size());
+  EXPECT_TRUE(section1_successful);
+  EXPECT_EQ(section1_expected, section1_actual);
+
+  bool section2_successful = ElfFileImpl32::ApplyOatPatches(
+      oat_patches.data(), oat_patches.data() + oat_patches.size(),
+      ".section2", delta,
+      section2_actual.data(), section2_actual.data() + section2_actual.size());
+  EXPECT_TRUE(section2_successful);
+  EXPECT_EQ(section2_expected, section2_actual);
+}
+
+#endif
+
 }  // namespace art