Add support for running 5.1.1 dex2oat.

This update 5.1.1 to include product/mako/system/framework/arm/boot.{art,oat}
and adds support for running 5.1.1 dex2oat in tools/dex2oat.py and ToolHelper.

Bug: 79191363
Change-Id: I6a35f775bd94d9622b8be41b3c2a3a1689af96ef
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index d4639a1..caeebd9 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -475,7 +475,7 @@
         .put(DexVm.ART_8_1_0_HOST, "marlin")
         .put(DexVm.ART_7_0_0_HOST, "angler")
         .put(DexVm.ART_6_0_1_HOST, "angler")
-        .put(DexVm.ART_5_1_1_HOST, "<missing>")
+        .put(DexVm.ART_5_1_1_HOST, "mako")
         .put(DexVm.ART_4_4_4_HOST, "<missing>")
         .put(DexVm.ART_4_0_4_HOST, "<missing>");
     PRODUCT = builder.build();
@@ -504,6 +504,10 @@
     return getDexVmPath(vm).resolve("product").resolve(PRODUCT.get(vm));
   }
 
+  private static String getArchString(DexVm vm) {
+    return vm.isOlderThanOrEqual(DexVm.ART_5_1_1_HOST) ? "arm" : "arm64";
+  }
+
   private static Path getProductBootImagePath(DexVm vm) {
     return getProductPath(vm).resolve("system").resolve("framework").resolve("boot.art");
   }
@@ -1438,39 +1442,40 @@
   }
 
   public static void runDex2Oat(Path file, Path outFile) throws IOException {
-    DexVm vm = getDexVm();
-    if (vm.isOlderThanOrEqual(DexVm.ART_5_1_1_HOST)) {
-      // TODO(b/79191363): Support running dex2oat for past android versions.
-      // Run default dex2oat for tests on old runtimes.
-      vm = DexVm.ART_DEFAULT;
-    }
-    runDex2Oat(file, outFile, vm);
+    runDex2Oat(file, outFile, getDexVm());
   }
 
   public static void runDex2Oat(Path file, Path outFile, DexVm vm) throws IOException {
-    Assume.assumeTrue(ToolHelper.isDex2OatSupported());
+    ProcessResult result = runDex2OatRaw(file, outFile, vm);
+    if (result.exitCode != 0) {
+      fail("dex2oat failed, exit code " + result.exitCode + ", stderr:\n" + result.stderr);
+    }
+    if (result.stderr != null && result.stderr.contains("Verification error")) {
+      fail("Verification error: \n" + result.stderr);
+    }
+  }
+
+  public static ProcessResult runDex2OatRaw(Path file, Path outFile, DexVm vm) throws IOException {
     // TODO(jmhenaff): find a way to run this on windows (push dex and run on device/emulator?)
-    Assume.assumeTrue(!ToolHelper.isWindows());
+    Assume.assumeTrue(ToolHelper.isDex2OatSupported());
+    if (vm.isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
+      // Run default dex2oat for tests on dalvik runtimes.
+      vm = DexVm.ART_DEFAULT;
+    }
     assert Files.exists(file);
     assert ByteStreams.toByteArray(Files.newInputStream(file)).length > 0;
     List<String> command = new ArrayList<>();
     command.add(getDex2OatPath(vm).toString());
-    command.add("--android-root=" + getProductPath(vm));
+    command.add("--android-root=" + getProductPath(vm) + "/system");
     command.add("--runtime-arg");
     command.add("-Xnorelocate");
-    command.add("--boot-image=" + getProductBootImagePath(vm));
     command.add("--dex-file=" + file.toAbsolutePath());
     command.add("--oat-file=" + outFile.toAbsolutePath());
-    command.add("--instruction-set=arm64");
+    // TODO(zerny): Create a proper interface for invoking dex2oat. Hardcoding arch here is a hack!
+    command.add("--instruction-set=" + getArchString(vm));
     ProcessBuilder builder = new ProcessBuilder(command);
     builder.environment().put("LD_LIBRARY_PATH", getDexVmLibPath(vm).toString());
-    ProcessResult result = runProcess(builder);
-    if (result.exitCode != 0) {
-      fail("dex2oat failed, exit code " + result.exitCode + ", stderr:\n" + result.stderr);
-    }
-    if (result.stderr.contains("Verification error")) {
-      fail("Verification error: \n" + result.stderr);
-    }
+    return runProcess(builder);
   }
 
   public static ProcessResult runProguardRaw(
diff --git a/tools/dex2oat.py b/tools/dex2oat.py
index eab424f..1e2cffd 100755
--- a/tools/dex2oat.py
+++ b/tools/dex2oat.py
@@ -16,8 +16,7 @@
   'default',
   '7.0.0',
   '6.0.1',
-  # TODO(b/79191363): Build a boot image for 5.1.1 dex2oat.
-  # '5.1.1',
+  '5.1.1',
 ]
 
 DIRS = {
@@ -34,6 +33,13 @@
   '5.1.1': 'mako',
 }
 
+ARCHS = {
+  'default': 'arm64',
+  '7.0.0': 'arm64',
+  '6.0.1': 'arm64',
+  '5.1.1': 'arm',
+}
+
 def ParseOptions():
   parser = optparse.OptionParser()
   parser.add_option('--version',
@@ -74,15 +80,15 @@
       oatfile = os.path.join(temp, "out.oat")
     base = os.path.join(LINUX_DIR, DIRS[version])
     product = PRODUCTS[version]
+    arch = ARCHS[version]
     cmd = [
       os.path.join(base, 'bin', 'dex2oat'),
-      '--android-root=' + os.path.join(base, 'product', product),
+      '--android-root=' + os.path.join(base, 'product', product, 'system'),
       '--runtime-arg',
       '-Xnorelocate',
-      '--boot-image=' + os.path.join(base, 'product', product, 'system', 'framework', 'boot.art'),
       '--dex-file=' + dexfile,
       '--oat-file=' + oatfile,
-      '--instruction-set=arm64',
+      '--instruction-set=' + arch,
     ]
     env = {"LD_LIBRARY_PATH": os.path.join(base, 'lib')}
     utils.PrintCmd(cmd)
diff --git a/tools/linux/art-5.1.1.tar.gz.sha1 b/tools/linux/art-5.1.1.tar.gz.sha1
index 2b6f07a..d7f86b0 100644
--- a/tools/linux/art-5.1.1.tar.gz.sha1
+++ b/tools/linux/art-5.1.1.tar.gz.sha1
@@ -1 +1 @@
-737072daed9a7cd4ef046b7ea8a60aa7b1b6c65d
\ No newline at end of file
+7c1b10e333a5a028db7f74a989d9edfe168900bf
\ No newline at end of file