ART: Make patchoat more resistant

Disable relocation, disallow dex-file fallback. These are unwelcome
when patching.

Refactor to have one set of options.

Bug: 73887870
Test: m test-art-host
Test: Flash-wipe device, boot
Change-Id: Ic7698cb83d1a8b4bb318af472f388dc88981c49c
diff --git a/patchoat/patchoat.cc b/patchoat/patchoat.cc
index 3df6409..b9a9a69 100644
--- a/patchoat/patchoat.cc
+++ b/patchoat/patchoat.cc
@@ -65,6 +65,8 @@
 
 using android::base::StringPrintf;
 
+namespace {
+
 static const OatHeader* GetOatHeader(const ElfFile* elf_file) {
   uint64_t off = 0;
   if (!elf_file->GetSectionOffsetAndSize(".rodata", &off, nullptr)) {
@@ -127,6 +129,38 @@
   return true;
 }
 
+// Holder class for runtime options and related objects.
+class PatchoatRuntimeOptionsHolder {
+ public:
+  PatchoatRuntimeOptionsHolder(const std::string& image_location, InstructionSet isa) {
+    options_.push_back(std::make_pair("compilercallbacks", &callbacks_));
+    img_ = "-Ximage:" + image_location;
+    options_.push_back(std::make_pair(img_.c_str(), nullptr));
+    isa_name_ = GetInstructionSetString(isa);
+    options_.push_back(std::make_pair("imageinstructionset",
+                                      reinterpret_cast<const void*>(isa_name_.c_str())));
+    options_.push_back(std::make_pair("-Xno-sig-chain", nullptr));
+    // We do not want the runtime to attempt to patch the image.
+    options_.push_back(std::make_pair("-Xnorelocate", nullptr));
+    // Don't try to compile.
+    options_.push_back(std::make_pair("-Xnoimage-dex2oat", nullptr));
+    // Do not accept broken image.
+    options_.push_back(std::make_pair("-Xno-dex-file-fallback", nullptr));
+  }
+
+  const RuntimeOptions& GetRuntimeOptions() {
+    return options_;
+  }
+
+ private:
+  RuntimeOptions options_;
+  NoopCompilerCallbacks callbacks_;
+  std::string isa_name_;
+  std::string img_;
+};
+
+}  // namespace
+
 bool PatchOat::GeneratePatch(
     const MemMap& original,
     const MemMap& relocated,
@@ -440,17 +474,10 @@
   TimingLogger::ScopedTiming t("Runtime Setup", timings);
 
   CHECK_NE(isa, InstructionSet::kNone);
-  const char* isa_name = GetInstructionSetString(isa);
 
   // Set up the runtime
-  RuntimeOptions options;
-  NoopCompilerCallbacks callbacks;
-  options.push_back(std::make_pair("compilercallbacks", &callbacks));
-  std::string img = "-Ximage:" + image_location;
-  options.push_back(std::make_pair(img.c_str(), nullptr));
-  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
-  options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
-  if (!Runtime::Create(options, false)) {
+  PatchoatRuntimeOptionsHolder options_holder(image_location, isa);
+  if (!Runtime::Create(options_holder.GetRuntimeOptions(), false)) {
     LOG(ERROR) << "Unable to initialize runtime";
     return false;
   }
@@ -608,17 +635,10 @@
   TimingLogger::ScopedTiming t("Runtime Setup", timings);
 
   CHECK_NE(isa, InstructionSet::kNone);
-  const char* isa_name = GetInstructionSetString(isa);
 
   // Set up the runtime
-  RuntimeOptions options;
-  NoopCompilerCallbacks callbacks;
-  options.push_back(std::make_pair("compilercallbacks", &callbacks));
-  std::string img = "-Ximage:" + image_location;
-  options.push_back(std::make_pair(img.c_str(), nullptr));
-  options.push_back(std::make_pair("imageinstructionset", reinterpret_cast<const void*>(isa_name)));
-  options.push_back(std::make_pair("-Xno-sig-chain", nullptr));
-  if (!Runtime::Create(options, false)) {
+  PatchoatRuntimeOptionsHolder options_holder(image_location, isa);
+  if (!Runtime::Create(options_holder.GetRuntimeOptions(), false)) {
     LOG(ERROR) << "Unable to initialize runtime";
     return false;
   }