Add patchoat tool to Art.

Add a new executable called patchoat to art. This tool takes already
compiled images and oat files and changes their base address, acting as
a cheap form of relocation.

Add a --include-patch-information flag to dex2oat and code to add
required patch information to oat files created with the quick compiler.

Bug: 15358152

Change-Id: Ie0c580db45bb14ec180deb84930def6c3628d97d
diff --git a/compiler/elf_fixup.cc b/compiler/elf_fixup.cc
index 404e3f8..60f76ef 100644
--- a/compiler/elf_fixup.cc
+++ b/compiler/elf_fixup.cc
@@ -69,97 +69,7 @@
   for (Elf32_Word i = 0; i < elf_file.GetDynamicNum(); i++) {
     Elf32_Dyn& elf_dyn = elf_file.GetDynamic(i);
     Elf32_Word d_tag = elf_dyn.d_tag;
-    bool elf_dyn_needs_fixup = false;
-    switch (d_tag) {
-      // case 1: well known d_tag values that imply Elf32_Dyn.d_un contains an address in d_ptr
-      case DT_PLTGOT:
-      case DT_HASH:
-      case DT_STRTAB:
-      case DT_SYMTAB:
-      case DT_RELA:
-      case DT_INIT:
-      case DT_FINI:
-      case DT_REL:
-      case DT_DEBUG:
-      case DT_JMPREL: {
-        elf_dyn_needs_fixup = true;
-        break;
-      }
-      // d_val or ignored values
-      case DT_NULL:
-      case DT_NEEDED:
-      case DT_PLTRELSZ:
-      case DT_RELASZ:
-      case DT_RELAENT:
-      case DT_STRSZ:
-      case DT_SYMENT:
-      case DT_SONAME:
-      case DT_RPATH:
-      case DT_SYMBOLIC:
-      case DT_RELSZ:
-      case DT_RELENT:
-      case DT_PLTREL:
-      case DT_TEXTREL:
-      case DT_BIND_NOW:
-      case DT_INIT_ARRAYSZ:
-      case DT_FINI_ARRAYSZ:
-      case DT_RUNPATH:
-      case DT_FLAGS: {
-        break;
-      }
-      // boundary values that should not be used
-      case DT_ENCODING:
-      case DT_LOOS:
-      case DT_HIOS:
-      case DT_LOPROC:
-      case DT_HIPROC: {
-        LOG(FATAL) << "Illegal d_tag value 0x" << std::hex << d_tag;
-        break;
-      }
-      default: {
-        // case 2: "regular" DT_* ranges where even d_tag values imply an address in d_ptr
-        if ((DT_ENCODING  < d_tag && d_tag < DT_LOOS)
-            || (DT_LOOS   < d_tag && d_tag < DT_HIOS)
-            || (DT_LOPROC < d_tag && d_tag < DT_HIPROC)) {
-          // Special case for MIPS which breaks the regular rules between DT_LOPROC and DT_HIPROC
-          if (elf_file.GetHeader().e_machine == EM_MIPS) {
-            switch (d_tag) {
-              case DT_MIPS_RLD_VERSION:
-              case DT_MIPS_TIME_STAMP:
-              case DT_MIPS_ICHECKSUM:
-              case DT_MIPS_IVERSION:
-              case DT_MIPS_FLAGS:
-              case DT_MIPS_LOCAL_GOTNO:
-              case DT_MIPS_CONFLICTNO:
-              case DT_MIPS_LIBLISTNO:
-              case DT_MIPS_SYMTABNO:
-              case DT_MIPS_UNREFEXTNO:
-              case DT_MIPS_GOTSYM:
-              case DT_MIPS_HIPAGENO: {
-                break;
-              }
-              case DT_MIPS_BASE_ADDRESS:
-              case DT_MIPS_CONFLICT:
-              case DT_MIPS_LIBLIST:
-              case DT_MIPS_RLD_MAP: {
-                elf_dyn_needs_fixup = true;
-                break;
-              }
-              default: {
-                LOG(FATAL) << "Unknown MIPS d_tag value 0x" << std::hex << d_tag;
-                break;
-              }
-            }
-          } else if ((elf_dyn.d_tag % 2) == 0) {
-            elf_dyn_needs_fixup = true;
-          }
-        } else {
-          LOG(FATAL) << "Unknown d_tag value 0x" << std::hex << d_tag;
-        }
-        break;
-      }
-    }
-    if (elf_dyn_needs_fixup) {
+    if (IsDynamicSectionPointer(d_tag, elf_file.GetHeader().e_machine)) {
       uint32_t d_ptr = elf_dyn.d_un.d_ptr;
       if (DEBUG_FIXUP) {
         LOG(INFO) << StringPrintf("In %s moving Elf32_Dyn[%d] from 0x%08x to 0x%08" PRIxPTR,