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/runtime/image.cc b/runtime/image.cc
index 528bfc6..93ec27d 100644
--- a/runtime/image.cc
+++ b/runtime/image.cc
@@ -24,7 +24,7 @@
 namespace art {
 
 const byte ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' };
-const byte ImageHeader::kImageVersion[] = { '0', '0', '7', '\0' };
+const byte ImageHeader::kImageVersion[] = { '0', '0', '8', '\0' };
 
 ImageHeader::ImageHeader(uint32_t image_begin,
                          uint32_t image_size,
@@ -45,6 +45,7 @@
     oat_data_begin_(oat_data_begin),
     oat_data_end_(oat_data_end),
     oat_file_end_(oat_file_end),
+    patch_delta_(0),
     image_roots_(image_roots) {
   CHECK_EQ(image_begin, RoundUp(image_begin, kPageSize));
   CHECK_EQ(oat_file_begin, RoundUp(oat_file_begin, kPageSize));
@@ -58,6 +59,17 @@
   memcpy(version_, kImageVersion, sizeof(kImageVersion));
 }
 
+void ImageHeader::RelocateImage(off_t delta) {
+  CHECK_ALIGNED(delta, kPageSize) << " patch delta must be page aligned";
+  image_begin_ += delta;
+  oat_file_begin_ += delta;
+  oat_data_begin_ += delta;
+  oat_data_end_ += delta;
+  oat_file_end_ += delta;
+  image_roots_ += delta;
+  patch_delta_ += delta;
+}
+
 bool ImageHeader::IsValid() const {
   if (memcmp(magic_, kImageMagic, sizeof(kImageMagic)) != 0) {
     return false;
@@ -65,6 +77,25 @@
   if (memcmp(version_, kImageVersion, sizeof(kImageVersion)) != 0) {
     return false;
   }
+  // Unsigned so wraparound is well defined.
+  if (image_begin_ >= image_begin_ + image_size_) {
+    return false;
+  }
+  if (oat_file_begin_ > oat_file_end_) {
+    return false;
+  }
+  if (oat_data_begin_ > oat_data_end_) {
+    return false;
+  }
+  if (oat_file_begin_ >= oat_data_begin_) {
+    return false;
+  }
+  if (image_roots_ <= image_begin_ || oat_file_begin_ <= image_roots_) {
+    return false;
+  }
+  if (!IsAligned<kPageSize>(patch_delta_)) {
+    return false;
+  }
   return true;
 }