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;
}