Add application image dex2oat options

Bug: 22858531
Change-Id: Ia6a2a832b20b5bb70672521cd06f679335efbd92
diff --git a/compiler/image_test.cc b/compiler/image_test.cc
index 21d582e..fd6cd82 100644
--- a/compiler/image_test.cc
+++ b/compiler/image_test.cc
@@ -97,8 +97,10 @@
   ASSERT_TRUE(dup_oat.get() != nullptr);
 
   {
-    bool success_image =
-        writer->Write(image_file.GetFilename(), dup_oat->GetPath(), dup_oat->GetPath());
+    bool success_image = writer->Write(kInvalidImageFd,
+                                       image_file.GetFilename(),
+                                       dup_oat->GetPath(),
+                                       dup_oat->GetPath());
     ASSERT_TRUE(success_image);
     bool success_fixup = ElfWriter::Fixup(dup_oat.get(), writer->GetOatDataBegin());
     ASSERT_TRUE(success_fixup);
diff --git a/compiler/image_writer.cc b/compiler/image_writer.cc
index 0e5a97f..af2a4f9 100644
--- a/compiler/image_writer.cc
+++ b/compiler/image_writer.cc
@@ -122,7 +122,8 @@
   return true;
 }
 
-bool ImageWriter::Write(const std::string& image_filename,
+bool ImageWriter::Write(int image_fd,
+                        const std::string& image_filename,
                         const std::string& oat_filename,
                         const std::string& oat_location) {
   CHECK(!image_filename.empty());
@@ -178,10 +179,13 @@
     LOG(ERROR) << "Failed to flush and close oat file " << oat_filename << " for " << oat_location;
     return false;
   }
-
-  std::unique_ptr<File> image_file(OS::CreateEmptyFile(image_filename.c_str()));
-  ImageHeader* image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
-  if (image_file.get() == nullptr) {
+  std::unique_ptr<File> image_file;
+  if (image_fd != kInvalidImageFd) {
+    image_file.reset(new File(image_fd, image_filename, unix_file::kCheckSafeUsage));
+  } else {
+    image_file.reset(OS::CreateEmptyFile(image_filename.c_str()));
+  }
+  if (image_file == nullptr) {
     LOG(ERROR) << "Failed to open image file " << image_filename;
     return false;
   }
@@ -192,6 +196,7 @@
   }
 
   // Write out the image + fields + methods.
+  ImageHeader* const image_header = reinterpret_cast<ImageHeader*>(image_->Begin());
   const auto write_count = image_header->GetImageSize();
   if (!image_file->WriteFully(image_->Begin(), write_count)) {
     PLOG(ERROR) << "Failed to write image file " << image_filename;
@@ -200,7 +205,8 @@
   }
 
   // Write out the image bitmap at the page aligned start of the image end.
-  const ImageSection& bitmap_section = image_header->GetImageSection(ImageHeader::kSectionImageBitmap);
+  const ImageSection& bitmap_section = image_header->GetImageSection(
+      ImageHeader::kSectionImageBitmap);
   CHECK_ALIGNED(bitmap_section.Offset(), kPageSize);
   if (!image_file->Write(reinterpret_cast<char*>(image_bitmap_->Begin()),
                          bitmap_section.Size(), bitmap_section.Offset())) {
diff --git a/compiler/image_writer.h b/compiler/image_writer.h
index e235bc4..7a2febc 100644
--- a/compiler/image_writer.h
+++ b/compiler/image_writer.h
@@ -41,6 +41,8 @@
 
 namespace art {
 
+static constexpr int kInvalidImageFd = -1;
+
 // Write a Space built during compilation for use during execution.
 class ImageWriter FINAL {
  public:
@@ -89,7 +91,11 @@
 
   uint8_t* GetOatFileBegin() const;
 
-  bool Write(const std::string& image_filename, const std::string& oat_filename,
+  // If image_fd is not kInvalidImageFd, then we use that for the file. Otherwise we open
+  // image_filename.
+  bool Write(int image_fd,
+             const std::string& image_filename,
+             const std::string& oat_filename,
              const std::string& oat_location)
       REQUIRES(!Locks::mutator_lock_);