Merge "Recovery partition uses the first architecture only"
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index ca863a7..ea8397d 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -243,6 +243,10 @@
 	return SanitizerRuntimeLibrary(t, "profile")
 }
 
+func ScudoRuntimeLibrary(t Toolchain) string {
+	return SanitizerRuntimeLibrary(t, "scudo")
+}
+
 func ToolPath(t Toolchain) string {
 	if p := t.ToolPath(); p != "" {
 		return p
diff --git a/cc/makevars.go b/cc/makevars.go
index 8b72dbb..5a912e1 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -302,6 +302,7 @@
 			ctx.Strict(secondPrefix+"UBSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerRuntimeLibrary(toolchain), ".so"))
 			ctx.Strict(secondPrefix+"UBSAN_MINIMAL_RUNTIME_LIBRARY", strings.TrimSuffix(config.UndefinedBehaviorSanitizerMinimalRuntimeLibrary(toolchain), ".a"))
 			ctx.Strict(secondPrefix+"TSAN_RUNTIME_LIBRARY", strings.TrimSuffix(config.ThreadSanitizerRuntimeLibrary(toolchain), ".so"))
+			ctx.Strict(secondPrefix+"SCUDO_RUNTIME_LIBRARY", strings.TrimSuffix(config.ScudoRuntimeLibrary(toolchain), ".so"))
 		}
 
 		// This is used by external/gentoo/...
diff --git a/cc/sanitize.go b/cc/sanitize.go
index e59edf5..38f4fc2 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -94,6 +94,7 @@
 		Safestack        *bool    `android:"arch_variant"`
 		Cfi              *bool    `android:"arch_variant"`
 		Integer_overflow *bool    `android:"arch_variant"`
+		Scudo            *bool    `android:"arch_variant"`
 
 		// Sanitizers to run in the diagnostic mode (as opposed to the release mode).
 		// Replaces abort() on error with a human-readable error message.
@@ -207,6 +208,10 @@
 			}
 		}
 
+		if found, globalSanitizers = removeFromList("scudo", globalSanitizers); found && s.Scudo == nil {
+			s.Scudo = boolPtr(true)
+		}
+
 		if len(globalSanitizers) > 0 {
 			ctx.ModuleErrorf("unknown global sanitizer option %s", globalSanitizers[0])
 		}
@@ -281,10 +286,16 @@
 	}
 
 	if ctx.Os() != android.Windows && (Bool(s.All_undefined) || Bool(s.Undefined) || Bool(s.Address) || Bool(s.Thread) ||
-		Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0) {
+		Bool(s.Coverage) || Bool(s.Safestack) || Bool(s.Cfi) || Bool(s.Integer_overflow) || len(s.Misc_undefined) > 0 ||
+		Bool(s.Scudo)) {
 		sanitize.Properties.SanitizerEnabled = true
 	}
 
+	// Disable Scudo if ASan or TSan is enabled.
+	if Bool(s.Address) || Bool(s.Thread) {
+		s.Scudo = nil
+	}
+
 	if Bool(s.Coverage) {
 		if !Bool(s.Address) {
 			ctx.ModuleErrorf(`Use of "coverage" also requires "address"`)
@@ -434,6 +445,10 @@
 		}
 	}
 
+	if Bool(sanitize.Properties.Sanitize.Scudo) {
+		sanitizers = append(sanitizers, "scudo")
+	}
+
 	if len(sanitizers) > 0 {
 		sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
 
@@ -471,6 +486,8 @@
 		runtimeLibrary = config.AddressSanitizerRuntimeLibrary(ctx.toolchain())
 	} else if Bool(sanitize.Properties.Sanitize.Thread) {
 		runtimeLibrary = config.ThreadSanitizerRuntimeLibrary(ctx.toolchain())
+	} else if Bool(sanitize.Properties.Sanitize.Scudo) {
+		runtimeLibrary = config.ScudoRuntimeLibrary(ctx.toolchain())
 	} else if len(diagSanitizers) > 0 || sanitize.Properties.UbsanRuntimeDep {
 		runtimeLibrary = config.UndefinedBehaviorSanitizerRuntimeLibrary(ctx.toolchain())
 	}
@@ -705,6 +722,7 @@
 
 func enableMinimalRuntime(sanitize *sanitize) bool {
 	if !Bool(sanitize.Properties.Sanitize.Address) &&
+		!Bool(sanitize.Properties.Sanitize.Scudo) &&
 		(Bool(sanitize.Properties.Sanitize.Integer_overflow) ||
 			len(sanitize.Properties.Sanitize.Misc_undefined) > 0) &&
 		!(Bool(sanitize.Properties.Sanitize.Diag.Integer_overflow) ||
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 308c141..dfba17e 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -69,7 +69,7 @@
 		blueprint.RuleParams{
 			Command: `rm -rf "$outDir" "$srcJarDir" "$stubsDir" && mkdir -p "$outDir" "$srcJarDir" "$stubsDir" && ` +
 				`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
-				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source 1.8 @$out.rsp @$srcJarDir/list ` +
+				`${config.JavaCmd} -jar ${config.MetalavaJar} -encoding UTF-8 -source $javaVersion @$out.rsp @$srcJarDir/list ` +
 				`$bootclasspathArgs $classpathArgs -sourcepath $sourcepath --no-banner --color --quiet ` +
 				`--stubs $stubsDir $opts && ` +
 				`${config.SoongZipCmd} -write_if_changed -d -o $docZip -C $outDir -D $outDir && ` +
@@ -85,7 +85,8 @@
 			RspfileContent: "$in",
 			Restat:         true,
 		},
-		"outDir", "srcJarDir", "stubsDir", "srcJars", "bootclasspathArgs", "classpathArgs", "sourcepath", "opts", "docZip")
+		"outDir", "srcJarDir", "stubsDir", "srcJars", "javaVersion", "bootclasspathArgs",
+		"classpathArgs", "sourcepath", "opts", "docZip")
 )
 
 func init() {
@@ -141,6 +142,9 @@
 		// Directories rooted at the Android.bp file to pass to aidl tool
 		Local_include_dirs []string
 	}
+
+	// If not blank, set the java version passed to javadoc as -source
+	Java_version *string
 }
 
 type ApiToCheck struct {
@@ -329,10 +333,16 @@
 		sdkDep := decodeSdkDep(ctx, String(j.properties.Sdk_version))
 		if sdkDep.useDefaultLibs {
 			ctx.AddDependency(ctx.Module(), bootClasspathTag, config.DefaultBootclasspathLibraries...)
+			if ctx.Config().TargetOpenJDK9() {
+				ctx.AddDependency(ctx.Module(), systemModulesTag, config.DefaultSystemModules)
+			}
 			if !Bool(j.properties.No_framework_libs) {
 				ctx.AddDependency(ctx.Module(), libTag, []string{"ext", "framework"}...)
 			}
 		} else if sdkDep.useModule {
+			if ctx.Config().TargetOpenJDK9() {
+				ctx.AddDependency(ctx.Module(), systemModulesTag, sdkDep.systemModules)
+			}
 			ctx.AddDependency(ctx.Module(), bootClasspathTag, sdkDep.modules...)
 		}
 	}
@@ -470,6 +480,15 @@
 			default:
 				ctx.ModuleErrorf("depends on non-java module %q", otherName)
 			}
+		case systemModulesTag:
+			if deps.systemModules != nil {
+				panic("Found two system module dependencies")
+			}
+			sm := module.(*SystemModules)
+			if sm.outputFile == nil {
+				panic("Missing directory for system module dependency")
+			}
+			deps.systemModules = sm.outputFile
 		}
 	})
 	// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
@@ -508,13 +527,16 @@
 	implicits = append(implicits, deps.classpath...)
 
 	var bootClasspathArgs, classpathArgs string
-	if ctx.Config().UseOpenJDK9() {
+
+	javaVersion := getJavaVersion(ctx, String(j.properties.Java_version), String(j.properties.Sdk_version))
+	if javaVersion == "1.9" || ctx.Config().UseOpenJDK9() {
 		if len(deps.bootClasspath) > 0 {
-			// For OpenJDK 9 we use --patch-module to define the core libraries code.
-			// TODO(tobiast): Reorganize this when adding proper support for OpenJDK 9
-			// modules. Here we treat all code in core libraries as being in java.base
-			// to work around the OpenJDK 9 module system. http://b/62049770
-			bootClasspathArgs = "--patch-module=java.base=" + strings.Join(deps.bootClasspath.Strings(), ":")
+			var systemModules classpath
+			if deps.systemModules != nil {
+				systemModules = append(systemModules, deps.systemModules)
+			}
+			bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
+			bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
 		}
 	} else {
 		if len(deps.bootClasspath.Strings()) > 0 {
@@ -528,7 +550,7 @@
 
 	implicits = append(implicits, j.srcJars...)
 
-	opts := "-J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
+	opts := "-source " + javaVersion + " -J-Xmx1024m -XDignore.symbol.file -Xdoclint:none"
 
 	ctx.Build(pctx, android.BuildParams{
 		Rule:           javadoc,
@@ -612,7 +634,23 @@
 	implicits = append(implicits, deps.bootClasspath...)
 	implicits = append(implicits, deps.classpath...)
 
-	bootClasspathArgs := deps.bootClasspath.FormJavaClassPath("-bootclasspath")
+	var bootClasspathArgs string
+	javaVersion := getJavaVersion(ctx, String(d.Javadoc.properties.Java_version), String(d.Javadoc.properties.Sdk_version))
+	if javaVersion == "1.9" {
+		if len(deps.bootClasspath) > 0 {
+			var systemModules classpath
+			if deps.systemModules != nil {
+				systemModules = append(systemModules, deps.systemModules)
+			}
+			bootClasspathArgs = systemModules.FormJavaSystemModulesPath("--system ", ctx.Device())
+			bootClasspathArgs = bootClasspathArgs + " --patch-module java.base=."
+		}
+	} else {
+		if len(deps.bootClasspath.Strings()) > 0 {
+			// For OpenJDK 8 we can use -bootclasspath to define the core libraries code.
+			bootClasspathArgs = deps.bootClasspath.FormJavaClassPath("-bootclasspath")
+		}
+	}
 	classpathArgs := deps.classpath.FormJavaClassPath("-classpath")
 
 	argFiles := ctx.ExpandSources(d.properties.Arg_files, nil)
@@ -801,7 +839,7 @@
 		date = `date -d`
 	}
 
-	doclavaOpts := "-source 1.8 -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
+	doclavaOpts := "-source " + javaVersion + " -J-Xmx1600m -J-XX:-OmitStackTraceInFastThrow -XDignore.symbol.file " +
 		"-doclet com.google.doclava.Doclava -docletpath " + jsilver.String() + ":" + doclava.String() + " " +
 		"-templatedir " + templateDir + " " + htmlDirArgs + " " + htmlDir2Args + " " +
 		"-hdf page.build " + ctx.Config().BuildId() + "-" + ctx.Config().BuildNumberFromFile() + " " +
@@ -844,6 +882,7 @@
 			"srcJarDir":         android.PathForModuleOut(ctx, "docs", "srcjars").String(),
 			"stubsDir":          android.PathForModuleOut(ctx, "docs", "stubsDir").String(),
 			"srcJars":           strings.Join(d.Javadoc.srcJars.Strings(), " "),
+			"javaVersion":       javaVersion,
 			"bootclasspathArgs": bootClasspathArgs,
 			"classpathArgs":     classpathArgs,
 			"sourcepath":        strings.Join(d.Javadoc.sourcepaths.Strings(), ":"),
diff --git a/java/java.go b/java/java.go
index 00ee531..969b063 100644
--- a/java/java.go
+++ b/java/java.go
@@ -788,6 +788,25 @@
 	return deps
 }
 
+func getJavaVersion(ctx android.ModuleContext, javaVersion, sdkVersion string) string {
+	var ret string
+	sdk := sdkStringToNumber(ctx, sdkVersion)
+	if javaVersion != "" {
+		ret = javaVersion
+	} else if ctx.Device() && sdk <= 23 {
+		ret = "1.7"
+	} else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
+		ret = "1.8"
+	} else if ctx.Device() && sdkVersion != "" && sdk == android.FutureApiLevel {
+		// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
+		ret = "1.8"
+	} else {
+		ret = "1.9"
+	}
+
+	return ret
+}
+
 func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags {
 
 	var flags javaBuilderFlags
@@ -813,19 +832,8 @@
 	}
 
 	// javaVersion flag.
-	sdk := sdkStringToNumber(ctx, String(j.deviceProperties.Sdk_version))
-	if j.properties.Java_version != nil {
-		flags.javaVersion = *j.properties.Java_version
-	} else if ctx.Device() && sdk <= 23 {
-		flags.javaVersion = "1.7"
-	} else if ctx.Device() && sdk <= 26 || !ctx.Config().TargetOpenJDK9() {
-		flags.javaVersion = "1.8"
-	} else if ctx.Device() && String(j.deviceProperties.Sdk_version) != "" && sdk == android.FutureApiLevel {
-		// TODO(ccross): once we generate stubs we should be able to use 1.9 for sdk_version: "current"
-		flags.javaVersion = "1.8"
-	} else {
-		flags.javaVersion = "1.9"
-	}
+	flags.javaVersion = getJavaVersion(ctx,
+		String(j.properties.Java_version), String(j.deviceProperties.Sdk_version))
 
 	// classpath
 	flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...)