Merge "Revert "Revert "Remove unnecessary warning suppression"""
diff --git a/Android.bp b/Android.bp
index 1b93c0d..9711c11 100644
--- a/Android.bp
+++ b/Android.bp
@@ -145,6 +145,7 @@
         "cc/util.go",
         "cc/vndk.go",
         "cc/vndk_prebuilt.go",
+        "cc/xom.go",
 
         "cc/cmakelists.go",
         "cc/compdb.go",
@@ -435,6 +436,7 @@
             src: "prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8/x86_64-w64-mingw32/lib/libwinpthread.a",
         },
     },
+    notice: ":mingw-libwinpthread-notice",
 }
 
 toolchain_library {
diff --git a/android/androidmk.go b/android/androidmk.go
index 7030523..18b26d9 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -40,6 +40,7 @@
 type AndroidMkData struct {
 	Class      string
 	SubName    string
+	DistFile   OptionalPath
 	OutputFile OptionalPath
 	Disabled   bool
 	Include    string
@@ -220,6 +221,45 @@
 		}
 	}
 
+	if len(amod.commonProperties.Dist.Targets) > 0 {
+		distFile := data.DistFile
+		if !distFile.Valid() {
+			distFile = data.OutputFile
+		}
+		if distFile.Valid() {
+			dest := filepath.Base(distFile.String())
+
+			if amod.commonProperties.Dist.Dest != nil {
+				var err error
+				dest, err = validateSafePath(*amod.commonProperties.Dist.Dest)
+				if err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			if amod.commonProperties.Dist.Suffix != nil {
+				ext := filepath.Ext(dest)
+				suffix := *amod.commonProperties.Dist.Suffix
+				dest = strings.TrimSuffix(dest, ext) + suffix + ext
+			}
+
+			if amod.commonProperties.Dist.Dir != nil {
+				var err error
+				dest, err = validateSafePath(*amod.commonProperties.Dist.Dir, dest)
+				if err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			goals := strings.Join(amod.commonProperties.Dist.Targets, " ")
+			fmt.Fprintln(&data.preamble, ".PHONY:", goals)
+			fmt.Fprintf(&data.preamble, "$(call dist-for-goals,%s,%s:%s)\n",
+				goals, distFile.String(), dest)
+		}
+	}
+
 	fmt.Fprintln(&data.preamble, "\ninclude $(CLEAR_VARS)")
 	fmt.Fprintln(&data.preamble, "LOCAL_PATH :=", filepath.Dir(ctx.BlueprintFile(mod)))
 	fmt.Fprintln(&data.preamble, "LOCAL_MODULE :=", name+data.SubName)
@@ -275,9 +315,10 @@
 		if amod.commonProperties.Owner != nil {
 			fmt.Fprintln(&data.preamble, "LOCAL_MODULE_OWNER :=", *amod.commonProperties.Owner)
 		}
-		if amod.commonProperties.Notice != nil {
-			fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", "$(LOCAL_PATH)/"+*amod.commonProperties.Notice)
-		}
+	}
+
+	if amod.noticeFile != nil {
+		fmt.Fprintln(&data.preamble, "LOCAL_NOTICE_FILE :=", amod.noticeFile.String())
 	}
 
 	if host {
diff --git a/android/arch.go b/android/arch.go
index 2543fca..1637a47 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -421,16 +421,9 @@
 	}
 }
 
-func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
-	var fields []reflect.StructField
-
-	ptr := prop.Kind() == reflect.Ptr
-	if ptr {
-		prop = prop.Elem()
-	}
-
-	for i := 0; i < prop.NumField(); i++ {
-		field := prop.Field(i)
+func filterArchStructFields(fields []reflect.StructField) []reflect.StructField {
+	var ret []reflect.StructField
+	for _, field := range fields {
 		if !proptools.HasTag(field, "android", "arch_variant") {
 			continue
 		}
@@ -466,8 +459,26 @@
 			panic("Interfaces are not supported in arch_variant properties")
 		}
 
-		fields = append(fields, field)
+		ret = append(ret, field)
 	}
+
+	return ret
+}
+
+func filterArchStruct(prop reflect.Type) (reflect.Type, bool) {
+	var fields []reflect.StructField
+
+	ptr := prop.Kind() == reflect.Ptr
+	if ptr {
+		prop = prop.Elem()
+	}
+
+	for i := 0; i < prop.NumField(); i++ {
+		fields = append(fields, prop.Field(i))
+	}
+
+	fields = filterArchStructFields(fields)
+
 	if len(fields) == 0 {
 		return nil, false
 	}
@@ -476,102 +487,152 @@
 	if ptr {
 		ret = reflect.PtrTo(ret)
 	}
+
 	return ret, true
 }
 
-func createArchType(props reflect.Type) reflect.Type {
-	props, ok := filterArchStruct(props)
+func filterArchStructSharded(prop reflect.Type) ([]reflect.Type, bool) {
+	var fields []reflect.StructField
+
+	ptr := prop.Kind() == reflect.Ptr
+	if ptr {
+		prop = prop.Elem()
+	}
+
+	for i := 0; i < prop.NumField(); i++ {
+		fields = append(fields, prop.Field(i))
+	}
+
+	fields = filterArchStructFields(fields)
+
+	if len(fields) == 0 {
+		return nil, false
+	}
+
+	shards := shardFields(fields, 10)
+
+	var ret []reflect.Type
+	for _, shard := range shards {
+		s := reflect.StructOf(shard)
+		if ptr {
+			s = reflect.PtrTo(s)
+		}
+		ret = append(ret, s)
+	}
+
+	return ret, true
+}
+
+func shardFields(fields []reflect.StructField, shardSize int) [][]reflect.StructField {
+	ret := make([][]reflect.StructField, 0, (len(fields)+shardSize-1)/shardSize)
+	for len(fields) > shardSize {
+		ret = append(ret, fields[0:shardSize])
+		fields = fields[shardSize:]
+	}
+	if len(fields) > 0 {
+		ret = append(ret, fields)
+	}
+	return ret
+}
+
+func createArchType(props reflect.Type) []reflect.Type {
+	propShards, ok := filterArchStructSharded(props)
 	if !ok {
 		return nil
 	}
 
-	variantFields := func(names []string) []reflect.StructField {
-		ret := make([]reflect.StructField, len(names))
+	var ret []reflect.Type
+	for _, props := range propShards {
 
-		for i, name := range names {
-			ret[i].Name = name
-			ret[i].Type = props
-		}
+		variantFields := func(names []string) []reflect.StructField {
+			ret := make([]reflect.StructField, len(names))
 
-		return ret
-	}
-
-	archFields := make([]reflect.StructField, len(archTypeList))
-	for i, arch := range archTypeList {
-		variants := []string{}
-
-		for _, archVariant := range archVariants[arch] {
-			archVariant := variantReplacer.Replace(archVariant)
-			variants = append(variants, proptools.FieldNameForProperty(archVariant))
-		}
-		for _, feature := range archFeatures[arch] {
-			feature := variantReplacer.Replace(feature)
-			variants = append(variants, proptools.FieldNameForProperty(feature))
-		}
-
-		fields := variantFields(variants)
-
-		fields = append([]reflect.StructField{reflect.StructField{
-			Name:      "BlueprintEmbed",
-			Type:      props,
-			Anonymous: true,
-		}}, fields...)
-
-		archFields[i] = reflect.StructField{
-			Name: arch.Field,
-			Type: reflect.StructOf(fields),
-		}
-	}
-	archType := reflect.StructOf(archFields)
-
-	multilibType := reflect.StructOf(variantFields([]string{"Lib32", "Lib64"}))
-
-	targets := []string{
-		"Host",
-		"Android64",
-		"Android32",
-		"Bionic",
-		"Linux",
-		"Not_windows",
-		"Arm_on_x86",
-		"Arm_on_x86_64",
-	}
-	for _, os := range osTypeList {
-		targets = append(targets, os.Field)
-
-		for _, archType := range osArchTypeMap[os] {
-			targets = append(targets, os.Field+"_"+archType.Name)
-
-			if os.Linux() {
-				target := "Linux_" + archType.Name
-				if !InList(target, targets) {
-					targets = append(targets, target)
-				}
+			for i, name := range names {
+				ret[i].Name = name
+				ret[i].Type = props
 			}
-			if os.Bionic() {
-				target := "Bionic_" + archType.Name
-				if !InList(target, targets) {
-					targets = append(targets, target)
+
+			return ret
+		}
+
+		archFields := make([]reflect.StructField, len(archTypeList))
+		for i, arch := range archTypeList {
+			variants := []string{}
+
+			for _, archVariant := range archVariants[arch] {
+				archVariant := variantReplacer.Replace(archVariant)
+				variants = append(variants, proptools.FieldNameForProperty(archVariant))
+			}
+			for _, feature := range archFeatures[arch] {
+				feature := variantReplacer.Replace(feature)
+				variants = append(variants, proptools.FieldNameForProperty(feature))
+			}
+
+			fields := variantFields(variants)
+
+			fields = append([]reflect.StructField{{
+				Name:      "BlueprintEmbed",
+				Type:      props,
+				Anonymous: true,
+			}}, fields...)
+
+			archFields[i] = reflect.StructField{
+				Name: arch.Field,
+				Type: reflect.StructOf(fields),
+			}
+		}
+		archType := reflect.StructOf(archFields)
+
+		multilibType := reflect.StructOf(variantFields([]string{"Lib32", "Lib64"}))
+
+		targets := []string{
+			"Host",
+			"Android64",
+			"Android32",
+			"Bionic",
+			"Linux",
+			"Not_windows",
+			"Arm_on_x86",
+			"Arm_on_x86_64",
+		}
+		for _, os := range osTypeList {
+			targets = append(targets, os.Field)
+
+			for _, archType := range osArchTypeMap[os] {
+				targets = append(targets, os.Field+"_"+archType.Name)
+
+				if os.Linux() {
+					target := "Linux_" + archType.Name
+					if !InList(target, targets) {
+						targets = append(targets, target)
+					}
+				}
+				if os.Bionic() {
+					target := "Bionic_" + archType.Name
+					if !InList(target, targets) {
+						targets = append(targets, target)
+					}
 				}
 			}
 		}
-	}
 
-	targetType := reflect.StructOf(variantFields(targets))
-	return reflect.StructOf([]reflect.StructField{
-		reflect.StructField{
-			Name: "Arch",
-			Type: archType,
-		},
-		reflect.StructField{
-			Name: "Multilib",
-			Type: multilibType,
-		},
-		reflect.StructField{
-			Name: "Target",
-			Type: targetType,
-		},
-	})
+		targetType := reflect.StructOf(variantFields(targets))
+		ret = append(ret, reflect.StructOf([]reflect.StructField{
+			{
+				Name: "Arch",
+				Type: archType,
+			},
+			{
+				Name: "Multilib",
+				Type: multilibType,
+			},
+			{
+				Name: "Target",
+				Type: targetType,
+			},
+		}))
+	}
+	return ret
 }
 
 var archPropTypeMap OncePer
@@ -596,21 +657,16 @@
 				propertiesValue.Interface()))
 		}
 
-		archPropType := archPropTypeMap.Once(t, func() interface{} {
+		archPropTypes := archPropTypeMap.Once(t, func() interface{} {
 			return createArchType(t)
-		})
+		}).([]reflect.Type)
 
-		if archPropType != nil {
-			base.archProperties = append(base.archProperties, reflect.New(archPropType.(reflect.Type)).Interface())
-		} else {
-			base.archProperties = append(base.archProperties, nil)
+		var archProperties []interface{}
+		for _, t := range archPropTypes {
+			archProperties = append(archProperties, reflect.New(t).Interface())
 		}
-	}
-
-	for _, asp := range base.archProperties {
-		if asp != nil {
-			m.AddProperties(asp)
-		}
+		base.archProperties = append(base.archProperties, archProperties)
+		m.AddProperties(archProperties...)
 	}
 
 	base.customizableProperties = m.GetProperties()
@@ -665,203 +721,205 @@
 		if a.archProperties[i] == nil {
 			continue
 		}
-		archProps := reflect.ValueOf(a.archProperties[i]).Elem()
+		for _, archProperties := range a.archProperties[i] {
+			archPropValues := reflect.ValueOf(archProperties).Elem()
 
-		archProp := archProps.FieldByName("Arch")
-		multilibProp := archProps.FieldByName("Multilib")
-		targetProp := archProps.FieldByName("Target")
+			archProp := archPropValues.FieldByName("Arch")
+			multilibProp := archPropValues.FieldByName("Multilib")
+			targetProp := archPropValues.FieldByName("Target")
 
-		var field string
-		var prefix string
+			var field string
+			var prefix string
 
-		// Handle arch-specific properties in the form:
-		// arch: {
-		//     arm64: {
-		//         key: value,
-		//     },
-		// },
-		t := arch.ArchType
-
-		if arch.ArchType != Common {
-			field := proptools.FieldNameForProperty(t.Name)
-			prefix := "arch." + t.Name
-			archStruct := a.appendProperties(ctx, genProps, archProp, field, prefix)
-
-			// Handle arch-variant-specific properties in the form:
+			// Handle arch-specific properties in the form:
 			// arch: {
-			//     variant: {
+			//     arm64: {
 			//         key: value,
 			//     },
 			// },
-			v := variantReplacer.Replace(arch.ArchVariant)
-			if v != "" {
-				field := proptools.FieldNameForProperty(v)
-				prefix := "arch." + t.Name + "." + v
-				a.appendProperties(ctx, genProps, archStruct, field, prefix)
+			t := arch.ArchType
+
+			if arch.ArchType != Common {
+				field := proptools.FieldNameForProperty(t.Name)
+				prefix := "arch." + t.Name
+				archStruct := a.appendProperties(ctx, genProps, archProp, field, prefix)
+
+				// Handle arch-variant-specific properties in the form:
+				// arch: {
+				//     variant: {
+				//         key: value,
+				//     },
+				// },
+				v := variantReplacer.Replace(arch.ArchVariant)
+				if v != "" {
+					field := proptools.FieldNameForProperty(v)
+					prefix := "arch." + t.Name + "." + v
+					a.appendProperties(ctx, genProps, archStruct, field, prefix)
+				}
+
+				// Handle cpu-variant-specific properties in the form:
+				// arch: {
+				//     variant: {
+				//         key: value,
+				//     },
+				// },
+				if arch.CpuVariant != arch.ArchVariant {
+					c := variantReplacer.Replace(arch.CpuVariant)
+					if c != "" {
+						field := proptools.FieldNameForProperty(c)
+						prefix := "arch." + t.Name + "." + c
+						a.appendProperties(ctx, genProps, archStruct, field, prefix)
+					}
+				}
+
+				// Handle arch-feature-specific properties in the form:
+				// arch: {
+				//     feature: {
+				//         key: value,
+				//     },
+				// },
+				for _, feature := range arch.ArchFeatures {
+					field := proptools.FieldNameForProperty(feature)
+					prefix := "arch." + t.Name + "." + feature
+					a.appendProperties(ctx, genProps, archStruct, field, prefix)
+				}
+
+				// Handle multilib-specific properties in the form:
+				// multilib: {
+				//     lib32: {
+				//         key: value,
+				//     },
+				// },
+				field = proptools.FieldNameForProperty(t.Multilib)
+				prefix = "multilib." + t.Multilib
+				a.appendProperties(ctx, genProps, multilibProp, field, prefix)
 			}
 
-			// Handle cpu-variant-specific properties in the form:
-			// arch: {
-			//     variant: {
+			// Handle host-specific properties in the form:
+			// target: {
+			//     host: {
 			//         key: value,
 			//     },
 			// },
-			if arch.CpuVariant != arch.ArchVariant {
-				c := variantReplacer.Replace(arch.CpuVariant)
-				if c != "" {
-					field := proptools.FieldNameForProperty(c)
-					prefix := "arch." + t.Name + "." + c
-					a.appendProperties(ctx, genProps, archStruct, field, prefix)
+			if os.Class == Host || os.Class == HostCross {
+				field = "Host"
+				prefix = "target.host"
+				a.appendProperties(ctx, genProps, targetProp, field, prefix)
+			}
+
+			// Handle target OS generalities of the form:
+			// target: {
+			//     bionic: {
+			//         key: value,
+			//     },
+			//     bionic_x86: {
+			//         key: value,
+			//     },
+			// }
+			if os.Linux() {
+				field = "Linux"
+				prefix = "target.linux"
+				a.appendProperties(ctx, genProps, targetProp, field, prefix)
+
+				if arch.ArchType != Common {
+					field = "Linux_" + arch.ArchType.Name
+					prefix = "target.linux_" + arch.ArchType.Name
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
 				}
 			}
 
-			// Handle arch-feature-specific properties in the form:
-			// arch: {
-			//     feature: {
+			if os.Bionic() {
+				field = "Bionic"
+				prefix = "target.bionic"
+				a.appendProperties(ctx, genProps, targetProp, field, prefix)
+
+				if arch.ArchType != Common {
+					field = "Bionic_" + t.Name
+					prefix = "target.bionic_" + t.Name
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				}
+			}
+
+			// Handle target OS properties in the form:
+			// target: {
+			//     linux_glibc: {
+			//         key: value,
+			//     },
+			//     not_windows: {
+			//         key: value,
+			//     },
+			//     linux_glibc_x86: {
+			//         key: value,
+			//     },
+			//     linux_glibc_arm: {
+			//         key: value,
+			//     },
+			//     android {
+			//         key: value,
+			//     },
+			//     android_arm {
+			//         key: value,
+			//     },
+			//     android_x86 {
 			//         key: value,
 			//     },
 			// },
-			for _, feature := range arch.ArchFeatures {
-				field := proptools.FieldNameForProperty(feature)
-				prefix := "arch." + t.Name + "." + feature
-				a.appendProperties(ctx, genProps, archStruct, field, prefix)
+			field = os.Field
+			prefix = "target." + os.Name
+			a.appendProperties(ctx, genProps, targetProp, field, prefix)
+
+			if arch.ArchType != Common {
+				field = os.Field + "_" + t.Name
+				prefix = "target." + os.Name + "_" + t.Name
+				a.appendProperties(ctx, genProps, targetProp, field, prefix)
 			}
 
-			// Handle multilib-specific properties in the form:
-			// multilib: {
-			//     lib32: {
+			if (os.Class == Host || os.Class == HostCross) && os != Windows {
+				field := "Not_windows"
+				prefix := "target.not_windows"
+				a.appendProperties(ctx, genProps, targetProp, field, prefix)
+			}
+
+			// Handle 64-bit device properties in the form:
+			// target {
+			//     android64 {
+			//         key: value,
+			//     },
+			//     android32 {
 			//         key: value,
 			//     },
 			// },
-			field = proptools.FieldNameForProperty(t.Multilib)
-			prefix = "multilib." + t.Multilib
-			a.appendProperties(ctx, genProps, multilibProp, field, prefix)
-		}
+			// WARNING: this is probably not what you want to use in your blueprints file, it selects
+			// options for all targets on a device that supports 64-bit binaries, not just the targets
+			// that are being compiled for 64-bit.  Its expected use case is binaries like linker and
+			// debuggerd that need to know when they are a 32-bit process running on a 64-bit device
+			if os.Class == Device {
+				if ctx.Config().Android64() {
+					field := "Android64"
+					prefix := "target.android64"
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				} else {
+					field := "Android32"
+					prefix := "target.android32"
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				}
 
-		// Handle host-specific properties in the form:
-		// target: {
-		//     host: {
-		//         key: value,
-		//     },
-		// },
-		if os.Class == Host || os.Class == HostCross {
-			field = "Host"
-			prefix = "target.host"
-			a.appendProperties(ctx, genProps, targetProp, field, prefix)
-		}
-
-		// Handle target OS generalities of the form:
-		// target: {
-		//     bionic: {
-		//         key: value,
-		//     },
-		//     bionic_x86: {
-		//         key: value,
-		//     },
-		// }
-		if os.Linux() {
-			field = "Linux"
-			prefix = "target.linux"
-			a.appendProperties(ctx, genProps, targetProp, field, prefix)
-
-			if arch.ArchType != Common {
-				field = "Linux_" + arch.ArchType.Name
-				prefix = "target.linux_" + arch.ArchType.Name
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
-			}
-		}
-
-		if os.Bionic() {
-			field = "Bionic"
-			prefix = "target.bionic"
-			a.appendProperties(ctx, genProps, targetProp, field, prefix)
-
-			if arch.ArchType != Common {
-				field = "Bionic_" + t.Name
-				prefix = "target.bionic_" + t.Name
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
-			}
-		}
-
-		// Handle target OS properties in the form:
-		// target: {
-		//     linux_glibc: {
-		//         key: value,
-		//     },
-		//     not_windows: {
-		//         key: value,
-		//     },
-		//     linux_glibc_x86: {
-		//         key: value,
-		//     },
-		//     linux_glibc_arm: {
-		//         key: value,
-		//     },
-		//     android {
-		//         key: value,
-		//     },
-		//     android_arm {
-		//         key: value,
-		//     },
-		//     android_x86 {
-		//         key: value,
-		//     },
-		// },
-		field = os.Field
-		prefix = "target." + os.Name
-		a.appendProperties(ctx, genProps, targetProp, field, prefix)
-
-		if arch.ArchType != Common {
-			field = os.Field + "_" + t.Name
-			prefix = "target." + os.Name + "_" + t.Name
-			a.appendProperties(ctx, genProps, targetProp, field, prefix)
-		}
-
-		if (os.Class == Host || os.Class == HostCross) && os != Windows {
-			field := "Not_windows"
-			prefix := "target.not_windows"
-			a.appendProperties(ctx, genProps, targetProp, field, prefix)
-		}
-
-		// Handle 64-bit device properties in the form:
-		// target {
-		//     android64 {
-		//         key: value,
-		//     },
-		//     android32 {
-		//         key: value,
-		//     },
-		// },
-		// WARNING: this is probably not what you want to use in your blueprints file, it selects
-		// options for all targets on a device that supports 64-bit binaries, not just the targets
-		// that are being compiled for 64-bit.  Its expected use case is binaries like linker and
-		// debuggerd that need to know when they are a 32-bit process running on a 64-bit device
-		if os.Class == Device {
-			if ctx.Config().Android64() {
-				field := "Android64"
-				prefix := "target.android64"
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
-			} else {
-				field := "Android32"
-				prefix := "target.android32"
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
-			}
-
-			if (arch.ArchType == X86 && (hasArmAbi(arch) ||
-				hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
-				(arch.ArchType == Arm &&
-					hasX86AndroidArch(ctx.Config().Targets[Android])) {
-				field := "Arm_on_x86"
-				prefix := "target.arm_on_x86"
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
-			}
-			if (arch.ArchType == X86_64 && (hasArmAbi(arch) ||
-				hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
-				(arch.ArchType == Arm &&
-					hasX8664AndroidArch(ctx.Config().Targets[Android])) {
-				field := "Arm_on_x86_64"
-				prefix := "target.arm_on_x86_64"
-				a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				if (arch.ArchType == X86 && (hasArmAbi(arch) ||
+					hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
+					(arch.ArchType == Arm &&
+						hasX86AndroidArch(ctx.Config().Targets[Android])) {
+					field := "Arm_on_x86"
+					prefix := "target.arm_on_x86"
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				}
+				if (arch.ArchType == X86_64 && (hasArmAbi(arch) ||
+					hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
+					(arch.ArchType == Arm &&
+						hasX8664AndroidArch(ctx.Config().Targets[Android])) {
+					field := "Arm_on_x86_64"
+					prefix := "target.arm_on_x86_64"
+					a.appendProperties(ctx, genProps, targetProp, field, prefix)
+				}
 			}
 		}
 	}
@@ -1025,6 +1083,7 @@
 		{"arm", "armv7-a-neon", "denver", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "krait", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "kryo", []string{"armeabi-v7a"}},
+		{"arm", "armv7-a-neon", "kryo385", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "exynos-m1", []string{"armeabi-v7a"}},
 		{"arm", "armv7-a-neon", "exynos-m2", []string{"armeabi-v7a"}},
 		{"arm64", "armv8-a", "cortex-a53", []string{"arm64-v8a"}},
@@ -1036,6 +1095,7 @@
 		{"arm64", "armv8-a", "exynos-m2", []string{"arm64-v8a"}},
 		{"arm64", "armv8-2a", "cortex-a75", []string{"arm64-v8a"}},
 		{"arm64", "armv8-2a", "cortex-a76", []string{"arm64-v8a"}},
+		{"arm64", "armv8-2a", "kryo385", []string{"arm64-v8a"}},
 		{"mips", "mips32-fp", "", []string{"mips"}},
 		{"mips", "mips32r2-fp", "", []string{"mips"}},
 		{"mips", "mips32r2-fp-xburst", "", []string{"mips"}},
diff --git a/android/config.go b/android/config.go
index 695a298..54c9da8 100644
--- a/android/config.go
+++ b/android/config.go
@@ -351,6 +351,10 @@
 
 var _ bootstrap.ConfigBlueprintToolLocation = (*config)(nil)
 
+func (c *config) HostToolPath(ctx PathContext, tool string) Path {
+	return PathForOutput(ctx, "host", c.PrebuiltOS(), "bin", tool)
+}
+
 // HostSystemTool looks for non-hermetic tools from the system we're running on.
 // Generally shouldn't be used, but useful to find the XCode SDK, etc.
 func (c *config) HostSystemTool(name string) string {
@@ -478,7 +482,7 @@
 }
 
 func (c *config) MinSupportedSdkVersion() int {
-	return 14
+	return 16
 }
 
 func (c *config) DefaultAppTargetSdkInt() int {
@@ -577,6 +581,10 @@
 	return Bool(c.productVariables.Debuggable)
 }
 
+func (c *config) Eng() bool {
+	return Bool(c.productVariables.Eng)
+}
+
 func (c *config) DevicePrefer32BitApps() bool {
 	return Bool(c.productVariables.DevicePrefer32BitApps)
 }
@@ -622,6 +630,14 @@
 	}
 }
 
+func (c *config) EnableXOM() bool {
+	if c.productVariables.EnableXOM == nil {
+		return false
+	} else {
+		return Bool(c.productVariables.EnableXOM)
+	}
+}
+
 func (c *config) Android64() bool {
 	for _, t := range c.Targets[Android] {
 		if t.Arch.ArchType.Multilib == "lib64" {
@@ -859,6 +875,13 @@
 	return PrefixInList(path, *c.productVariables.CFIIncludePaths)
 }
 
+func (c *config) XOMDisabledForPath(path string) bool {
+	if c.productVariables.XOMExcludePaths == nil {
+		return false
+	}
+	return PrefixInList(path, *c.productVariables.XOMExcludePaths)
+}
+
 func (c *config) VendorConfig(name string) VendorConfig {
 	return vendorConfig(c.productVariables.VendorVars[name])
 }
@@ -881,6 +904,14 @@
 	return Bool(c.productVariables.Ndk_abis)
 }
 
+func (c *config) ExcludeDraftNdkApis() bool {
+	return Bool(c.productVariables.Exclude_draft_ndk_apis)
+}
+
+func (c *config) FlattenApex() bool {
+	return Bool(c.productVariables.FlattenApex)
+}
+
 func stringSlice(s *[]string) []string {
 	if s != nil {
 		return *s
diff --git a/android/module.go b/android/module.go
index 556c73d..dc0c856 100644
--- a/android/module.go
+++ b/android/module.go
@@ -265,6 +265,24 @@
 	// relative path to a file to include in the list of notices for the device
 	Notice *string
 
+	Dist struct {
+		// copy the output of this module to the $DIST_DIR when `dist` is specified on the
+		// command line and  any of these targets are also on the command line, or otherwise
+		// built
+		Targets []string `android:"arch_variant"`
+
+		// The name of the output artifact. This defaults to the basename of the output of
+		// the module.
+		Dest *string `android:"arch_variant"`
+
+		// The directory within the dist directory to store the artifact. Defaults to the
+		// top level directory ("").
+		Dir *string `android:"arch_variant"`
+
+		// A suffix to add to the artifact file name (before any extension).
+		Suffix *string `android:"arch_variant"`
+	} `android:"arch_variant"`
+
 	// Set by TargetMutator
 	CompileTarget       Target   `blueprint:"mutated"`
 	CompileMultiTargets []Target `blueprint:"mutated"`
@@ -280,7 +298,10 @@
 }
 
 type hostAndDeviceProperties struct {
-	Host_supported   *bool
+	// If set to true, build a variant of the module for the host.  Defaults to false.
+	Host_supported *bool
+
+	// If set to true, build a variant of the module for the device.  Defaults to true.
 	Device_supported *bool
 }
 
@@ -432,12 +453,13 @@
 	variableProperties      variableProperties
 	hostAndDeviceProperties hostAndDeviceProperties
 	generalProperties       []interface{}
-	archProperties          []interface{}
+	archProperties          [][]interface{}
 	customizableProperties  []interface{}
 
 	noAddressSanitizer bool
 	installFiles       Paths
 	checkbuildFiles    Paths
+	noticeFile         Path
 
 	// Used by buildTargetSingleton to create checkbuild and per-directory build targets
 	// Only set on the final variant of each module
@@ -778,6 +800,25 @@
 	}
 	ctx.Variable(pctx, "moduleDescSuffix", s)
 
+	// Some common property checks for properties that will be used later in androidmk.go
+	if a.commonProperties.Dist.Dest != nil {
+		_, err := validateSafePath(*a.commonProperties.Dist.Dest)
+		if err != nil {
+			ctx.PropertyErrorf("dist.dest", "%s", err.Error())
+		}
+	}
+	if a.commonProperties.Dist.Dir != nil {
+		_, err := validateSafePath(*a.commonProperties.Dist.Dir)
+		if err != nil {
+			ctx.PropertyErrorf("dist.dir", "%s", err.Error())
+		}
+	}
+	if a.commonProperties.Dist.Suffix != nil {
+		if strings.Contains(*a.commonProperties.Dist.Suffix, "/") {
+			ctx.PropertyErrorf("dist.suffix", "Suffix may not contain a '/' character.")
+		}
+	}
+
 	if a.Enabled() {
 		a.module.GenerateAndroidBuildActions(ctx)
 		if ctx.Failed() {
@@ -786,6 +827,11 @@
 
 		a.installFiles = append(a.installFiles, ctx.installFiles...)
 		a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
+
+		if a.commonProperties.Notice != nil {
+			// For filegroup-based notice file references.
+			a.noticeFile = ctx.ExpandSource(*a.commonProperties.Notice, "notice")
+		}
 	}
 
 	if a == ctx.FinalModule().(Module).base() {
@@ -1307,6 +1353,13 @@
 	srcFiles := ctx.ExpandSourcesSubDir([]string{srcFile}, nil, "")
 	if len(srcFiles) == 1 {
 		return srcFiles[0]
+	} else if len(srcFiles) == 0 {
+		if ctx.Config().AllowMissingDependencies() {
+			ctx.AddMissingDependencies([]string{srcFile})
+		} else {
+			ctx.PropertyErrorf(prop, "%s path %s does not exist", prop, srcFile)
+		}
+		return nil
 	} else {
 		ctx.PropertyErrorf(prop, "module providing %s must produce exactly one file", prop)
 		return nil
diff --git a/android/mutator.go b/android/mutator.go
index b9c44e8..b77c2f0 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -207,6 +207,11 @@
 func depsMutator(ctx BottomUpMutatorContext) {
 	if m, ok := ctx.Module().(Module); ok && m.Enabled() {
 		m.DepsMutator(ctx)
+
+		// For filegroup-based notice file references.
+		if m.base().commonProperties.Notice != nil {
+			ExtractSourceDeps(ctx, m.base().commonProperties.Notice)
+		}
 	}
 }
 
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index 83c38db..f7d08cc 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -40,6 +40,10 @@
 	// optional name for the installed file. If unspecified, name of the module is used as the file name
 	Filename *string `android:"arch_variant"`
 
+	// when set to true, and filename property is not set, the name for the installed file
+	// is the same as the file name of the source file.
+	Filename_from_src *bool `android:"arch_variant"`
+
 	// Make this module available when building for recovery.
 	Recovery_available *bool
 
@@ -106,8 +110,16 @@
 func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) {
 	p.sourceFilePath = ctx.ExpandSource(String(p.properties.Src), "src")
 	filename := String(p.properties.Filename)
+	filename_from_src := Bool(p.properties.Filename_from_src)
 	if filename == "" {
-		filename = ctx.ModuleName()
+		if filename_from_src {
+			filename = p.sourceFilePath.Base()
+		} else {
+			filename = ctx.ModuleName()
+		}
+	} else if filename_from_src {
+		ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+		return
 	}
 	p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
 	p.installDirPath = PathForModuleInstall(ctx, "etc", String(p.properties.Sub_dir))
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index 1ecdf79..27736ba 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -106,3 +106,27 @@
 		t.Errorf("expected foo.installed.conf, got %q", p.outputFilePath.Base())
 	}
 }
+
+func TestPrebuiltEtcGlob(t *testing.T) {
+	ctx := testPrebuiltEtc(t, `
+		prebuilt_etc {
+			name: "my_foo",
+			src: "foo.*",
+		}
+		prebuilt_etc {
+			name: "my_bar",
+			src: "bar.*",
+			filename_from_src: true,
+		}
+	`)
+
+	p := ctx.ModuleForTests("my_foo", "android_common_core").Module().(*PrebuiltEtc)
+	if p.outputFilePath.Base() != "my_foo" {
+		t.Errorf("expected my_foo, got %q", p.outputFilePath.Base())
+	}
+
+	p = ctx.ModuleForTests("my_bar", "android_common_core").Module().(*PrebuiltEtc)
+	if p.outputFilePath.Base() != "bar.conf" {
+		t.Errorf("expected bar.conf, got %q", p.outputFilePath.Base())
+	}
+}
diff --git a/android/variable.go b/android/variable.go
index 2686049..f496008 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -54,17 +54,19 @@
 			Cflags []string
 		}
 
-		Device_uses_hwc2 struct {
-			Cflags []string
-		}
-
 		Override_rs_driver struct {
 			Cflags []string
 		}
 
 		// Product_is_iot is true for Android Things devices.
 		Product_is_iot struct {
-			Cflags []string
+			Cflags       []string
+			Enabled      bool
+			Exclude_srcs []string
+			Init_rc      []string
+			Shared_libs  []string
+			Srcs         []string
+			Static_libs  []string
 		}
 
 		// treble_linker_namespaces is true when the system/vendor linker namespace separation is
@@ -184,7 +186,6 @@
 	UseGoma                    *bool `json:",omitempty"`
 	Debuggable                 *bool `json:",omitempty"`
 	Eng                        *bool `json:",omitempty"`
-	Device_uses_hwc2           *bool `json:",omitempty"`
 	Treble_linker_namespaces   *bool `json:",omitempty"`
 	Enforce_vintf_manifest     *bool `json:",omitempty"`
 	Pdk                        *bool `json:",omitempty"`
@@ -205,6 +206,9 @@
 	CFIExcludePaths *[]string `json:",omitempty"`
 	CFIIncludePaths *[]string `json:",omitempty"`
 
+	EnableXOM       *bool     `json:",omitempty"`
+	XOMExcludePaths *[]string `json:",omitempty"`
+
 	VendorPath          *string `json:",omitempty"`
 	OdmPath             *string `json:",omitempty"`
 	ProductPath         *string `json:",omitempty"`
@@ -249,7 +253,10 @@
 
 	VendorVars map[string]map[string]string `json:",omitempty"`
 
-	Ndk_abis *bool `json:",omitempty"`
+	Ndk_abis               *bool `json:",omitempty"`
+	Exclude_draft_ndk_apis *bool `json:",omitempty"`
+
+	FlattenApex *bool `json:",omitempty"`
 }
 
 func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 3e7c0a7..8a652db 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -38,7 +38,7 @@
 	// TODO(b/113082813) make this configurable using config.fs syntax
 	generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{
 		Command: `echo '/ 1000 1000 0755' > ${out} && ` +
-			`echo '/manifest.json 1000 1000 0644' >> ${out} && ` +
+			`echo '/apex_manifest.json 1000 1000 0644' >> ${out} && ` +
 			`echo ${ro_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0644"}' >> ${out} && ` +
 			`echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0755"}' >> ${out}`,
 		Description: "fs_config ${out}",
@@ -52,7 +52,7 @@
 		Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` +
 			`(${copy_commands}) && ` +
 			`APEXER_TOOL_PATH=${tool_path} ` +
-			`${apexer} --verbose --force --manifest ${manifest} ` +
+			`${apexer} --force --manifest ${manifest} ` +
 			`--file_contexts ${file_contexts} ` +
 			`--canned_fs_config ${canned_fs_config} ` +
 			`--key ${key} ${image_dir} ${out} `,
@@ -61,6 +61,21 @@
 			"${soong_zip}", "${zipalign}", "${aapt2}"},
 		Description: "APEX ${image_dir} => ${out}",
 	}, "tool_path", "image_dir", "copy_commands", "manifest", "file_contexts", "canned_fs_config", "key")
+
+	apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule",
+		blueprint.RuleParams{
+			Command:     `${aapt2} convert --output-format proto $in -o $out`,
+			CommandDeps: []string{"${aapt2}"},
+		})
+
+	apexBundleRule = pctx.StaticRule("apexBundleRule", blueprint.RuleParams{
+		Command: `${zip2zip} -i $in -o $out ` +
+			`apex_payload.img:apex/${abi}.img ` +
+			`apex_manifest.json:root/apex_manifest.json ` +
+			`AndroidManifest.xml:manifest/AndroidManifest.xml`,
+		CommandDeps: []string{"${zip2zip}"},
+		Description: "app bundle",
+	}, "abi")
 )
 
 var apexSuffix = ".apex"
@@ -102,6 +117,7 @@
 	pctx.HostBinToolVariable("resize2fs", "resize2fs")
 	pctx.HostBinToolVariable("sefcontext_compile", "sefcontext_compile")
 	pctx.HostBinToolVariable("soong_zip", "soong_zip")
+	pctx.HostBinToolVariable("zip2zip", "zip2zip")
 	pctx.HostBinToolVariable("zipalign", "zipalign")
 
 	android.RegisterModuleType("apex", apexBundleFactory)
@@ -123,10 +139,10 @@
 // can be built for the apex bundles.
 func apexDepsMutator(mctx android.TopDownMutatorContext) {
 	if _, ok := mctx.Module().(*apexBundle); ok {
-		apexBundleName := mctx.Module().Name()
+		apexBundleName := mctx.ModuleName()
 		mctx.WalkDeps(func(child, parent android.Module) bool {
 			if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() {
-				moduleName := am.Name() + "-" + am.Target().String()
+				moduleName := mctx.OtherModuleName(am) + "-" + am.Target().String()
 				bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]
 				if !ok {
 					bundleNames = make(map[string]bool)
@@ -144,7 +160,7 @@
 // Create apex variations if a module is included in APEX(s).
 func apexMutator(mctx android.BottomUpMutatorContext) {
 	if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
-		moduleName := am.Name() + "-" + am.Target().String()
+		moduleName := mctx.ModuleName() + "-" + am.Target().String()
 		if bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]; ok {
 			variations := []string{"platform"}
 			for bn := range bundleNames {
@@ -168,11 +184,13 @@
 
 type apexBundleProperties struct {
 	// Json manifest file describing meta info of this APEX bundle. Default:
-	// "manifest.json"
+	// "apex_manifest.json"
 	Manifest *string
 
-	// File contexts file for setting security context to each file in this APEX bundle
-	// Default: "file_contexts".
+	// Determines the file contexts file for setting security context to each file in this APEX bundle.
+	// Specifically, when this is set to <value>, /system/sepolicy/apex/<value>_file_contexts file is
+	// used.
+	// Default: <name_of_this_module>
 	File_contexts *string
 
 	// List of native shared libs that are embedded inside this APEX bundle
@@ -228,14 +246,52 @@
 	}
 }
 
+type apexFileClass int
+
+const (
+	etc apexFileClass = iota
+	nativeSharedLib
+	nativeExecutable
+	javaSharedLib
+)
+
+func (class apexFileClass) NameInMake() string {
+	switch class {
+	case etc:
+		return "ETC"
+	case nativeSharedLib:
+		return "SHARED_LIBRARIES"
+	case nativeExecutable:
+		return "EXECUTABLES"
+	case javaSharedLib:
+		return "JAVA_LIBRARIES"
+	default:
+		panic(fmt.Errorf("unkonwn class %d", class))
+	}
+}
+
+type apexFile struct {
+	builtFile  android.Path
+	moduleName string
+	archType   android.ArchType
+	installDir string
+	class      apexFileClass
+}
+
 type apexBundle struct {
 	android.ModuleBase
 	android.DefaultableModuleBase
 
 	properties apexBundleProperties
 
-	outputFile android.WritablePath
-	installDir android.OutputPath
+	bundleModuleFile android.WritablePath
+	outputFile       android.WritablePath
+	installDir       android.OutputPath
+
+	// list of files to be included in this apex
+	filesInfo []apexFile
+
+	flattened bool
 }
 
 func addDependenciesForNativeModules(ctx android.BottomUpMutatorContext,
@@ -362,7 +418,7 @@
 
 func getCopyManifestForJavaLibrary(java *java.Library) (fileToCopy android.Path, dirInApex string) {
 	dirInApex = "javalib"
-	fileToCopy = java.Srcs()[0]
+	fileToCopy = java.DexJarFile()
 	return
 }
 
@@ -373,8 +429,7 @@
 }
 
 func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
-	// files to copy -> dir in apex
-	copyManifest := make(map[android.Path]string)
+	filesInfo := []apexFile{}
 
 	var keyFile android.Path
 	var certificate java.Certificate
@@ -388,7 +443,7 @@
 			case sharedLibTag:
 				if cc, ok := child.(*cc.Module); ok {
 					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
-					copyManifest[fileToCopy] = dirInApex
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib})
 					return true
 				} else {
 					ctx.PropertyErrorf("native_shared_libs", "%q is not a cc_library or cc_library_shared module", depName)
@@ -396,7 +451,7 @@
 			case executableTag:
 				if cc, ok := child.(*cc.Module); ok {
 					fileToCopy, dirInApex := getCopyManifestForExecutable(cc)
-					copyManifest[fileToCopy] = dirInApex
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeExecutable})
 					return true
 				} else {
 					ctx.PropertyErrorf("binaries", "%q is not a cc_binary module", depName)
@@ -404,7 +459,11 @@
 			case javaLibTag:
 				if java, ok := child.(*java.Library); ok {
 					fileToCopy, dirInApex := getCopyManifestForJavaLibrary(java)
-					copyManifest[fileToCopy] = dirInApex
+					if fileToCopy == nil {
+						ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
+					} else {
+						filesInfo = append(filesInfo, apexFile{fileToCopy, depName, java.Arch().ArchType, dirInApex, javaSharedLib})
+					}
 					return true
 				} else {
 					ctx.PropertyErrorf("java_libs", "%q is not a java_library module", depName)
@@ -412,7 +471,7 @@
 			case prebuiltTag:
 				if prebuilt, ok := child.(*android.PrebuiltEtc); ok {
 					fileToCopy, dirInApex := getCopyManifestForPrebuiltEtc(prebuilt)
-					copyManifest[fileToCopy] = dirInApex
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, prebuilt.Arch().ArchType, dirInApex, etc})
 					return true
 				} else {
 					ctx.PropertyErrorf("prebuilts", "%q is not a prebuilt_etc module", depName)
@@ -436,8 +495,9 @@
 			// indirect dependencies
 			if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() && am.IsInstallableToApex() {
 				if cc, ok := child.(*cc.Module); ok {
+					depName := ctx.OtherModuleName(child)
 					fileToCopy, dirInApex := getCopyManifestForNativeLibrary(cc)
-					copyManifest[fileToCopy] = dirInApex
+					filesInfo = append(filesInfo, apexFile{fileToCopy, depName, cc.Arch().ArchType, dirInApex, nativeSharedLib})
 					return true
 				}
 			}
@@ -450,6 +510,42 @@
 		return
 	}
 
+	// remove duplicates in filesInfo
+	removeDup := func(filesInfo []apexFile) []apexFile {
+		encountered := make(map[android.Path]bool)
+		result := []apexFile{}
+		for _, f := range filesInfo {
+			if !encountered[f.builtFile] {
+				encountered[f.builtFile] = true
+				result = append(result, f)
+			}
+		}
+		return result
+	}
+	filesInfo = removeDup(filesInfo)
+
+	// to have consistent build rules
+	sort.Slice(filesInfo, func(i, j int) bool {
+		return filesInfo[i].builtFile.String() < filesInfo[j].builtFile.String()
+	})
+
+	// prepend the name of this APEX to the module names. These names will be the names of
+	// modules that will be defined if the APEX is flattened.
+	for i := range filesInfo {
+		filesInfo[i].moduleName = ctx.ModuleName() + "." + filesInfo[i].moduleName
+	}
+
+	a.flattened = ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
+	a.installDir = android.PathForModuleInstall(ctx, "apex")
+	a.filesInfo = filesInfo
+	if ctx.Config().FlattenApex() {
+		a.buildFlattenedApex(ctx)
+	} else {
+		a.buildUnflattenedApex(ctx, keyFile, certificate)
+	}
+}
+
+func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext, keyFile android.Path, certificate java.Certificate) {
 	cert := String(a.properties.Certificate)
 	if cert != "" && android.SrcIsModule(cert) == "" {
 		defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
@@ -465,45 +561,51 @@
 	// files and dirs that will be created in apex
 	var readOnlyPaths []string
 	var executablePaths []string // this also includes dirs
-	for fileToCopy, dirInApex := range copyManifest {
-		pathInApex := filepath.Join(dirInApex, fileToCopy.Base())
-		if dirInApex == "bin" {
+	for _, f := range a.filesInfo {
+		pathInApex := filepath.Join(f.installDir, f.builtFile.Base())
+		if f.installDir == "bin" {
 			executablePaths = append(executablePaths, pathInApex)
 		} else {
 			readOnlyPaths = append(readOnlyPaths, pathInApex)
 		}
-		if !android.InList(dirInApex, executablePaths) {
-			executablePaths = append(executablePaths, dirInApex)
+		if !android.InList(f.installDir, executablePaths) {
+			executablePaths = append(executablePaths, f.installDir)
 		}
 	}
 	sort.Strings(readOnlyPaths)
 	sort.Strings(executablePaths)
 	cannedFsConfig := android.PathForModuleOut(ctx, "canned_fs_config")
-	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
-		Rule:   generateFsConfig,
-		Output: cannedFsConfig,
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        generateFsConfig,
+		Output:      cannedFsConfig,
+		Description: "generate fs config",
 		Args: map[string]string{
 			"ro_paths":   strings.Join(readOnlyPaths, " "),
 			"exec_paths": strings.Join(executablePaths, " "),
 		},
 	})
 
-	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "manifest.json"))
-	fileContexts := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.File_contexts, "file_contexts"))
+	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
 
-	unsignedOutputFile := android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix+".unsigned")
+	fcName := proptools.StringDefault(a.properties.File_contexts, ctx.ModuleName())
+	fileContextsPath := "system/sepolicy/apex/" + fcName + "-file_contexts"
+	fileContextsOptionalPath := android.ExistentPathForSource(ctx, fileContextsPath)
+	if !fileContextsOptionalPath.Valid() {
+		ctx.ModuleErrorf("Cannot find file_contexts file: %q", fileContextsPath)
+		return
+	}
+	fileContexts := fileContextsOptionalPath.Path()
+
+	unsignedOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+apexSuffix+".unsigned")
 
 	filesToCopy := []android.Path{}
-	for file := range copyManifest {
-		filesToCopy = append(filesToCopy, file)
+	for _, f := range a.filesInfo {
+		filesToCopy = append(filesToCopy, f.builtFile)
 	}
-	sort.Slice(filesToCopy, func(i, j int) bool {
-		return filesToCopy[i].String() < filesToCopy[j].String()
-	})
 
 	copyCommands := []string{}
-	for _, src := range filesToCopy {
-		dest := filepath.Join(copyManifest[src], src.Base())
+	for i, src := range filesToCopy {
+		dest := filepath.Join(a.filesInfo[i].installDir, src.Base())
 		dest_path := filepath.Join(android.PathForModuleOut(ctx, "image").String(), dest)
 		copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(dest_path))
 		copyCommands = append(copyCommands, "cp "+src.String()+" "+dest_path)
@@ -512,10 +614,11 @@
 	implicitInputs = append(implicitInputs, cannedFsConfig, manifest, fileContexts, keyFile)
 	outHostBinDir := android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "bin").String()
 	prebuiltSdkToolsBinDir := filepath.Join("prebuilts", "sdk", "tools", runtime.GOOS, "bin")
-	ctx.ModuleBuild(pctx, android.ModuleBuildParams{
-		Rule:      apexRule,
-		Implicits: implicitInputs,
-		Output:    unsignedOutputFile,
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexRule,
+		Implicits:   implicitInputs,
+		Output:      unsignedOutputFile,
+		Description: "apex",
 		Args: map[string]string{
 			"tool_path":        outHostBinDir + ":" + prebuiltSdkToolsBinDir,
 			"image_dir":        android.PathForModuleOut(ctx, "image").String(),
@@ -527,7 +630,34 @@
 		},
 	})
 
-	a.outputFile = android.PathForModuleOut(ctx, a.ModuleBase.Name()+apexSuffix)
+	var abis []string
+	for _, target := range ctx.MultiTargets() {
+		abis = append(abis, target.Arch.Abi[0])
+	}
+	abis = android.FirstUniqueStrings(abis)
+
+	apexProtoFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".pb"+apexSuffix)
+	bundleModuleFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-base.zip")
+	a.bundleModuleFile = bundleModuleFile
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexProtoConvertRule,
+		Input:       unsignedOutputFile,
+		Output:      apexProtoFile,
+		Description: "apex proto convert",
+	})
+
+	ctx.Build(pctx, android.BuildParams{
+		Rule:        apexBundleRule,
+		Input:       apexProtoFile,
+		Output:      bundleModuleFile,
+		Description: "apex bundle module",
+		Args: map[string]string{
+			"abi": strings.Join(abis, "."),
+		},
+	})
+
+	a.outputFile = android.PathForModuleOut(ctx, ctx.ModuleName()+apexSuffix)
 	ctx.Build(pctx, android.BuildParams{
 		Rule:        java.Signapk,
 		Description: "signapk",
@@ -535,25 +665,76 @@
 		Input:       unsignedOutputFile,
 		Args: map[string]string{
 			"certificates": strings.Join([]string{certificate.Pem.String(), certificate.Key.String()}, " "),
+			"flags":        "-a 4096", //alignment
 		},
 	})
+}
 
-	a.installDir = android.PathForModuleInstall(ctx, "apex")
+func (a *apexBundle) buildFlattenedApex(ctx android.ModuleContext) {
+	// For flattened APEX, do nothing but make sure that apex_manifest.json file is also copied along
+	// with other ordinary files.
+	manifest := android.PathForModuleSrc(ctx, proptools.StringDefault(a.properties.Manifest, "apex_manifest.json"))
+	a.filesInfo = append(a.filesInfo, apexFile{manifest, ctx.ModuleName() + ".apex_manifest.json", android.Common, ".", etc})
+
+	for _, fi := range a.filesInfo {
+		dir := filepath.Join("apex", ctx.ModuleName(), fi.installDir)
+		ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.builtFile.Base(), fi.builtFile)
+	}
 }
 
 func (a *apexBundle) AndroidMk() android.AndroidMkData {
-	return android.AndroidMkData{
-		Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
-			fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
-			fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
-			fmt.Fprintln(w, "LOCAL_MODULE :=", name)
-			fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
-			fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
-			fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString()))
-			fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name+apexSuffix)
-			fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key))
-			fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
-		}}
+	if a.flattened {
+		return android.AndroidMkData{
+			Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+				moduleNames := []string{}
+				for _, fi := range a.filesInfo {
+					if !android.InList(fi.moduleName, moduleNames) {
+						moduleNames = append(moduleNames, fi.moduleName)
+					}
+				}
+				fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+				fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+				fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", strings.Join(moduleNames, " "))
+				fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
+
+				for _, fi := range a.filesInfo {
+					fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+					fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+					fmt.Fprintln(w, "LOCAL_MODULE :=", fi.moduleName)
+					fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString(), name, fi.installDir))
+					fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", fi.builtFile.Base())
+					fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", fi.builtFile.String())
+					fmt.Fprintln(w, "LOCAL_MODULE_CLASS :=", fi.class.NameInMake())
+					archStr := fi.archType.String()
+					if archStr != "common" {
+						fmt.Fprintln(w, "LOCAL_MODULE_TARGET_ARCH :=", archStr)
+					}
+					if fi.class == javaSharedLib {
+						fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
+						fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
+						fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
+					} else {
+						fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
+					}
+				}
+			}}
+	} else {
+		return android.AndroidMkData{
+			Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
+				fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)")
+				fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir)
+				fmt.Fprintln(w, "LOCAL_MODULE :=", name)
+				fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") // do we need a new class?
+				fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", a.outputFile.String())
+				fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join("$(OUT_DIR)", a.installDir.RelPathString()))
+				fmt.Fprintln(w, "LOCAL_INSTALLED_MODULE_STEM :=", name+apexSuffix)
+				fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES :=", String(a.properties.Key))
+				fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
+
+				fmt.Fprintln(w, "ALL_MODULES.$(LOCAL_MODULE).BUNDLE :=", a.bundleModuleFile.String())
+			}}
+	}
 }
 
 func apexBundleFactory() android.Module {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 324b5bc..f5e04bb 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -70,6 +70,12 @@
 				if len(c.Properties.AndroidMkSharedLibs) > 0 {
 					fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES := "+strings.Join(c.Properties.AndroidMkSharedLibs, " "))
 				}
+				if len(c.Properties.AndroidMkStaticLibs) > 0 {
+					fmt.Fprintln(w, "LOCAL_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkStaticLibs, " "))
+				}
+				if len(c.Properties.AndroidMkWholeStaticLibs) > 0 {
+					fmt.Fprintln(w, "LOCAL_WHOLE_STATIC_LIBRARIES := "+strings.Join(c.Properties.AndroidMkWholeStaticLibs, " "))
+				}
 				fmt.Fprintln(w, "LOCAL_SOONG_LINK_TYPE :=", c.getMakeLinkType())
 				if c.useVndk() {
 					fmt.Fprintln(w, "LOCAL_USE_VNDK := true")
@@ -137,11 +143,15 @@
 		ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 			fmt.Fprintln(w, "LOCAL_SOONG_TOC :=", library.toc().String())
 			fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
+			if len(library.Properties.Overrides) > 0 {
+				fmt.Fprintln(w, "LOCAL_OVERRIDES_MODULES := "+strings.Join(library.Properties.Overrides, " "))
+			}
 		})
 	} else if library.header() {
 		ret.Class = "HEADER_LIBRARIES"
 	}
 
+	ret.DistFile = library.distFile
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		library.androidMkWriteExportedFlags(w)
 		fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES := ")
@@ -185,6 +195,7 @@
 	ctx.subAndroidMk(ret, binary.baseInstaller)
 
 	ret.Class = "EXECUTABLES"
+	ret.DistFile = binary.distFile
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
 		fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String())
 		if len(binary.symlinks) > 0 {
diff --git a/cc/binary.go b/cc/binary.go
index 15db2ad..6923f2b 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -88,6 +88,9 @@
 
 	// Output archive of gcno coverage information
 	coverageOutputFile android.OptionalPath
+
+	// Location of the file that should be copied to dist dir when requested
+	distFile android.OptionalPath
 }
 
 var _ linker = (*binaryDecorator)(nil)
@@ -330,10 +333,23 @@
 			flagsToBuilderFlags(flags), afterPrefixSymbols)
 	}
 
-	if Bool(binary.baseLinker.Properties.Use_version_lib) && ctx.Host() {
-		versionedOutputFile := outputFile
-		outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
-		binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+	if Bool(binary.baseLinker.Properties.Use_version_lib) {
+		if ctx.Host() {
+			versionedOutputFile := outputFile
+			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
+			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		} else {
+			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
+			binary.distFile = android.OptionalPathForPath(versionedOutputFile)
+
+			if binary.stripper.needsStrip(ctx) {
+				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
+				binary.distFile = android.OptionalPathForPath(out)
+				binary.stripper.strip(ctx, versionedOutputFile, out, builderFlags)
+			}
+
+			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		}
 	}
 
 	if ctx.Os() == android.LinuxBionic && !binary.static() {
diff --git a/cc/builder.go b/cc/builder.go
index 6d5b595..bf35f84 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -231,8 +231,6 @@
 	ldFlags         string
 	libFlags        string
 	yaccFlags       string
-	protoFlags      string
-	protoOutParams  string
 	tidyFlags       string
 	sAbiFlags       string
 	yasmFlags       string
@@ -242,7 +240,6 @@
 	tidy            bool
 	coverage        bool
 	sAbiDump        bool
-	protoRoot       bool
 
 	systemIncludeFlags string
 
@@ -252,6 +249,14 @@
 	stripKeepMiniDebugInfo bool
 	stripAddGnuDebuglink   bool
 	stripUseLlvmStrip      bool
+
+	protoDeps        android.Paths
+	protoFlags       string
+	protoOutTypeFlag string
+	protoOutParams   string
+	protoC           bool
+	protoOptionsFile bool
+	protoRoot        bool
 }
 
 type Objects struct {
diff --git a/cc/cc.go b/cc/cc.go
index fcd8a45..8a0bf71 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -53,6 +53,9 @@
 		ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
 		ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
 
+		ctx.TopDown("scs_deps", sanitizerDepsMutator(scs))
+		ctx.BottomUp("scs", sanitizerMutator(scs)).Parallel()
+
 		ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
 		ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
 
@@ -130,8 +133,6 @@
 	CppFlags        []string // Flags that apply to C++ source files
 	ToolingCppFlags []string // Flags that apply to C++ source files parsed by clang LibTooling tools
 	YaccFlags       []string // Flags that apply to Yacc source files
-	protoFlags      []string // Flags that apply to proto source files
-	protoOutParams  []string // Flags that modify the output of proto generated files
 	aidlFlags       []string // Flags that apply to aidl source files
 	rsFlags         []string // Flags that apply to renderscript source files
 	LdFlags         []string // Flags that apply to linker command lines
@@ -148,7 +149,6 @@
 	Tidy      bool
 	Coverage  bool
 	SAbiDump  bool
-	ProtoRoot bool
 
 	RequiredInstructionSet string
 	DynamicLinker          string
@@ -157,6 +157,14 @@
 	LdFlagsDeps android.Paths // Files depended on by linker flags
 
 	GroupStaticLibs bool
+
+	protoDeps        android.Paths
+	protoFlags       []string // Flags that apply to proto source files
+	protoOutTypeFlag string   // The output type, --cpp_out for example
+	protoOutParams   []string // Flags that modify the output of proto generated files
+	protoC           bool     // Whether to use C instead of C++
+	protoOptionsFile bool     // Whether to look for a .options file next to the .proto
+	ProtoRoot        bool
 }
 
 type ObjectLinkerProperties struct {
@@ -175,10 +183,12 @@
 	// Minimum sdk version supported when compiling against the ndk
 	Sdk_version *string
 
-	AndroidMkSharedLibs  []string `blueprint:"mutated"`
-	AndroidMkRuntimeLibs []string `blueprint:"mutated"`
-	HideFromMake         bool     `blueprint:"mutated"`
-	PreventInstall       bool     `blueprint:"mutated"`
+	AndroidMkSharedLibs      []string `blueprint:"mutated"`
+	AndroidMkStaticLibs      []string `blueprint:"mutated"`
+	AndroidMkRuntimeLibs     []string `blueprint:"mutated"`
+	AndroidMkWholeStaticLibs []string `blueprint:"mutated"`
+	HideFromMake             bool     `blueprint:"mutated"`
+	PreventInstall           bool     `blueprint:"mutated"`
 
 	UseVndk bool `blueprint:"mutated"`
 
@@ -237,6 +247,7 @@
 	baseModuleName() string
 	getVndkExtendsModuleName() string
 	isPgoCompile() bool
+	useClangLld(actx ModuleContext) bool
 }
 
 type ModuleContext interface {
@@ -277,6 +288,7 @@
 	linkerDeps(ctx DepsContext, deps Deps) Deps
 	linkerFlags(ctx ModuleContext, flags Flags) Flags
 	linkerProps() []interface{}
+	useClangLld(actx ModuleContext) bool
 
 	link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path
 	appendLdflags([]string)
@@ -350,6 +362,7 @@
 	vndkdep   *vndkdep
 	lto       *lto
 	pgo       *pgo
+	xom       *xom
 
 	androidMkSharedLibDeps []string
 
@@ -407,6 +420,9 @@
 	if c.pgo != nil {
 		c.AddProperties(c.pgo.props()...)
 	}
+	if c.xom != nil {
+		c.AddProperties(c.xom.props()...)
+	}
 	for _, feature := range c.features {
 		c.AddProperties(feature.props()...)
 	}
@@ -621,6 +637,10 @@
 	return ""
 }
 
+func (ctx *moduleContextImpl) useClangLld(actx ModuleContext) bool {
+	return ctx.mod.linker.useClangLld(actx)
+}
+
 func (ctx *moduleContextImpl) baseModuleName() string {
 	return ctx.mod.ModuleBase.BaseModuleName()
 }
@@ -648,6 +668,7 @@
 	module.vndkdep = &vndkdep{}
 	module.lto = &lto{}
 	module.pgo = &pgo{}
+	module.xom = &xom{}
 	return module
 }
 
@@ -764,6 +785,9 @@
 	if c.pgo != nil {
 		flags = c.pgo.flags(ctx, flags)
 	}
+	if c.xom != nil {
+		flags = c.xom.flags(ctx, flags)
+	}
 	for _, feature := range c.features {
 		flags = feature.flags(ctx, flags)
 	}
@@ -1265,7 +1289,8 @@
 		}
 		depIsDoubleLoadable := Bool(to.VendorProperties.Double_loadable)
 		if !depIsLlndk && !depIsVndkSp && !depIsDoubleLoadable && depIsVndk {
-			ctx.ModuleErrorf("links VNDK library %q that isn't double_loadable.",
+			ctx.ModuleErrorf("links VNDK library %q that isn't double loadable (not also LL-NDK, "+
+				"VNDK-SP, or explicitly marked as 'double_loadable').",
 				ctx.OtherModuleName(to))
 		}
 	}
@@ -1478,9 +1503,15 @@
 			// they merely serve as Make dependencies and do not affect this lib itself.
 			c.Properties.AndroidMkSharedLibs = append(
 				c.Properties.AndroidMkSharedLibs, makeLibName(depName))
+		case staticDepTag, staticExportDepTag, lateStaticDepTag:
+			c.Properties.AndroidMkStaticLibs = append(
+				c.Properties.AndroidMkStaticLibs, makeLibName(depName))
 		case runtimeDepTag:
 			c.Properties.AndroidMkRuntimeLibs = append(
 				c.Properties.AndroidMkRuntimeLibs, makeLibName(depName))
+		case wholeStaticDepTag:
+			c.Properties.AndroidMkWholeStaticLibs = append(
+				c.Properties.AndroidMkWholeStaticLibs, makeLibName(depName))
 		}
 	})
 
@@ -1610,7 +1641,6 @@
 		&VendorProperties{},
 		&BaseCompilerProperties{},
 		&BaseLinkerProperties{},
-		&MoreBaseLinkerProperties{},
 		&LibraryProperties{},
 		&FlagExporterProperties{},
 		&BinaryLinkerProperties{},
@@ -1626,6 +1656,7 @@
 		&VndkProperties{},
 		&LTOProperties{},
 		&PgoProperties{},
+		&XomProperties{},
 		&android.ProtoProperties{},
 	)
 
@@ -1726,6 +1757,7 @@
 
 	// Sanity check
 	vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
+	productSpecific := mctx.ProductSpecific()
 
 	if m.VendorProperties.Vendor_available != nil && vendorSpecific {
 		mctx.PropertyErrorf("vendor_available",
@@ -1735,6 +1767,11 @@
 
 	if vndkdep := m.vndkdep; vndkdep != nil {
 		if vndkdep.isVndk() {
+			if productSpecific {
+				mctx.PropertyErrorf("product_specific",
+					"product_specific must not be true when `vndk: {enabled: true}`")
+				return
+			}
 			if vendorSpecific {
 				if !vndkdep.isVndkExt() {
 					mctx.PropertyErrorf("vndk",
diff --git a/cc/cc_test.go b/cc/cc_test.go
index d6ffe51..41f633a 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -492,6 +492,21 @@
 	`)
 }
 
+func TestVndkMustNotBeProductSpecific(t *testing.T) {
+	// Check whether an error is emitted when a vndk lib has 'product_specific: true'.
+	testCcError(t, "product_specific must not be true when `vndk: {enabled: true}`", `
+		cc_library {
+			name: "libvndk",
+			product_specific: true,  // Cause error
+			vendor_available: true,
+			vndk: {
+				enabled: true,
+			},
+			nocrt: true,
+		}
+	`)
+}
+
 func TestVndkExt(t *testing.T) {
 	// This test checks the VNDK-Ext properties.
 	ctx := testCc(t, `
@@ -1545,6 +1560,43 @@
 	checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
 }
 
+func checkStaticLibs(t *testing.T, expected []string, module *Module) {
+	actual := module.Properties.AndroidMkStaticLibs
+	if !reflect.DeepEqual(actual, expected) {
+		t.Errorf("incorrect static_libs"+
+			"\nactual:   %v"+
+			"\nexpected: %v",
+			actual,
+			expected,
+		)
+	}
+}
+
+const staticLibAndroidBp = `
+	cc_library {
+		name: "lib1",
+	}
+	cc_library {
+		name: "lib2",
+		static_libs: ["lib1"],
+	}
+`
+
+func TestStaticLibDepExport(t *testing.T) {
+	ctx := testCc(t, staticLibAndroidBp)
+
+	// Check the shared version of lib2.
+	variant := "android_arm64_armv8-a_core_shared"
+	module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
+	checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
+
+	// Check the static version of lib2.
+	variant = "android_arm64_armv8-a_core_static"
+	module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
+	// libc++_static is linked additionally.
+	checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
+}
+
 var compilerFlagsTestCases = []struct {
 	in  string
 	out bool
diff --git a/cc/compiler.go b/cc/compiler.go
index 5ac5d79..ad1fc6d 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -299,6 +299,7 @@
 	}
 
 	if ctx.useSdk() {
+		// TODO: Switch to --sysroot.
 		// The NDK headers are installed to a common sysroot. While a more
 		// typical Soong approach would be to only make the headers for the
 		// library you're using available, we're trying to emulate the NDK
@@ -307,6 +308,7 @@
 			"-isystem "+getCurrentIncludePath(ctx).String(),
 			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
 
+		// TODO: Migrate to API suffixed triple?
 		// Traditionally this has come from android/api-level.h, but with the
 		// libc headers unified it must be set by the build system since we
 		// don't have per-API level copies of that header now.
@@ -316,14 +318,6 @@
 		}
 		flags.GlobalFlags = append(flags.GlobalFlags,
 			"-D__ANDROID_API__="+version)
-
-		// Until the full NDK has been migrated to using ndk_headers, we still
-		// need to add the legacy sysroot includes to get the full set of
-		// headers.
-		legacyIncludes := fmt.Sprintf(
-			"prebuilts/ndk/current/platforms/android-%s/arch-%s/usr/include",
-			ctx.sdkVersion(), ctx.Arch().ArchType.String())
-		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags, "-isystem "+legacyIncludes)
 	}
 
 	if ctx.useVndk() {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 6a63828..299799d 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -68,6 +68,10 @@
 		"kryo": []string{
 			"-mcpu=kryo",
 		},
+		"kryo385": []string{
+			// Use cortex-a53 because kryo385 is not supported in GCC/clang.
+			"-mcpu=cortex-a53",
+		},
 		"exynos-m1": []string{
 			"-mcpu=exynos-m1",
 		},
@@ -92,6 +96,7 @@
 		"cortex-a75",
 		"cortex-a76",
 		"kryo",
+		"kryo385",
 		"exynos-m1",
 		"exynos-m2",
 		"denver64")
@@ -144,6 +149,7 @@
 		"cortex-a75": "${config.Arm64ClangCortexA55Cflags}",
 		"cortex-a76": "${config.Arm64ClangCortexA55Cflags}",
 		"kryo":       "${config.Arm64ClangKryoCflags}",
+		"kryo385":    "${config.Arm64ClangCortexA53Cflags}",
 		"exynos-m1":  "${config.Arm64ClangExynosM1Cflags}",
 		"exynos-m2":  "${config.Arm64ClangExynosM2Cflags}",
 	}
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 75f5962..29378c6 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -66,6 +66,11 @@
 			"-mfloat-abi=softfp",
 			"-mfpu=neon-fp-armv8",
 		},
+		"armv8-2a": []string{
+			"-march=armv8.2-a",
+			"-mfloat-abi=softfp",
+			"-mfpu=neon-fp-armv8",
+		},
 	}
 
 	armClangCpuVariantCflags = map[string][]string{
@@ -146,6 +151,15 @@
 			// better solution comes around. See Bug 27340895
 			"-D__ARM_FEATURE_LPAE=1",
 		},
+		"kryo385": []string{
+			// Use cortex-a53 because kryo385 is not supported in GCC/clang.
+			"-mcpu=cortex-a53",
+			// Fake an ARM compiler flag as these processors support LPAE which GCC/clang
+			// don't advertise.
+			// TODO This is a hack and we need to add it for each processor that supports LPAE until some
+			// better solution comes around. See Bug 27340895
+			"-D__ARM_FEATURE_LPAE=1",
+		},
 	}
 )
 
@@ -161,6 +175,7 @@
 		"armv7-a",
 		"armv7-a-neon",
 		"armv8-a",
+		"armv8-2a",
 		"cortex-a7",
 		"cortex-a8",
 		"cortex-a9",
@@ -174,12 +189,14 @@
 		"cortex-a76",
 		"krait",
 		"kryo",
+		"kryo385",
 		"exynos-m1",
 		"exynos-m2",
 		"denver")
 
 	android.RegisterArchVariantFeatures(android.Arm, "armv7-a-neon", "neon")
 	android.RegisterArchVariantFeatures(android.Arm, "armv8-a", "neon")
+	android.RegisterArchVariantFeatures(android.Arm, "armv8-2a", "neon")
 
 	pctx.StaticVariable("armGccVersion", armGccVersion)
 
@@ -208,6 +225,8 @@
 		strings.Join(armClangArchVariantCflags["armv7-a-neon"], " "))
 	pctx.StaticVariable("ArmClangArmv8ACflags",
 		strings.Join(armClangArchVariantCflags["armv8-a"], " "))
+	pctx.StaticVariable("ArmClangArmv82ACflags",
+		strings.Join(armClangArchVariantCflags["armv8-2a"], " "))
 
 	// Clang cpu variant cflags
 	pctx.StaticVariable("ArmClangGenericCflags",
@@ -233,6 +252,7 @@
 		"armv7-a":      "${config.ArmClangArmv7ACflags}",
 		"armv7-a-neon": "${config.ArmClangArmv7ANeonCflags}",
 		"armv8-a":      "${config.ArmClangArmv8ACflags}",
+		"armv8-2a":     "${config.ArmClangArmv82ACflags}",
 	}
 
 	armClangCpuVariantCflagsVar = map[string]string{
@@ -248,6 +268,7 @@
 		"cortex-a75":     "${config.ArmClangCortexA55Cflags}",
 		"krait":          "${config.ArmClangKraitCflags}",
 		"kryo":           "${config.ArmClangKryoCflags}",
+		"kryo385":        "${config.ArmClangCortexA53Cflags}",
 		"exynos-m1":      "${config.ArmClangCortexA53Cflags}",
 		"exynos-m2":      "${config.ArmClangCortexA53Cflags}",
 		"denver":         "${config.ArmClangCortexA15Cflags}",
@@ -347,8 +368,8 @@
 		}
 	case "armv7-a":
 		fixCortexA8 = "-Wl,--fix-cortex-a8"
-	case "armv8-a":
-		// Nothing extra for armv8-a
+	case "armv8-a", "armv8-2a":
+		// Nothing extra for armv8-a/armv8-2a
 	default:
 		panic(fmt.Sprintf("Unknown ARM architecture version: %q", arch.ArchVariant))
 	}
diff --git a/cc/config/global.go b/cc/config/global.go
index d4f86b8..31f64fe 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -87,11 +87,6 @@
 
 	deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags),
 		[]string{
-			// TODO(b/109657296): needs --no-rosegment until Android
-			// stack unwinder can handle the read-only segment.
-			"-Wl,--no-rosegment",
-			"-Wl,--pack-dyn-relocs=android+relr",
-			"-Wl,--use-android-relr-tags",
 			"-fuse-ld=lld",
 		}...)
 
@@ -117,16 +112,16 @@
 	}
 
 	CStdVersion               = "gnu99"
-	CppStdVersion             = "gnu++14"
+	CppStdVersion             = "gnu++17"
 	ExperimentalCStdVersion   = "gnu11"
-	ExperimentalCppStdVersion = "gnu++1z"
+	ExperimentalCppStdVersion = "gnu++2a"
 
 	NdkMaxPrebuiltVersionInt = 27
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r344140"
-	ClangDefaultShortVersion = "8.0.3"
+	ClangDefaultVersion      = "clang-r344140b"
+	ClangDefaultShortVersion = "8.0.4"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
diff --git a/cc/config/x86_windows_host.go b/cc/config/x86_windows_host.go
index 6300a1b..e23c0a0 100644
--- a/cc/config/x86_windows_host.go
+++ b/cc/config/x86_windows_host.go
@@ -140,6 +140,9 @@
 	pctx.StaticVariable("WindowsX8664ClangCppflags", strings.Join(windowsX8664ClangCppflags, " "))
 
 	pctx.StaticVariable("WindowsIncludeFlags", strings.Join(windowsIncludeFlags, " "))
+	// Yasm flags
+	pctx.StaticVariable("WindowsX86YasmFlags", "-f win32 -m x86")
+	pctx.StaticVariable("WindowsX8664YasmFlags", "-f win64 -m amd64")
 }
 
 type toolchainWindows struct {
@@ -228,6 +231,14 @@
 	return "${config.WindowsClangLldflags} ${config.WindowsX8664ClangLldflags}"
 }
 
+func (t *toolchainWindowsX86) YasmFlags() string {
+	return "${config.WindowsX86YasmFlags}"
+}
+
+func (t *toolchainWindowsX8664) YasmFlags() string {
+	return "${config.WindowsX8664YasmFlags}"
+}
+
 func (t *toolchainWindows) ShlibSuffix() string {
 	return ".dll"
 }
diff --git a/cc/gen.go b/cc/gen.go
index 29a2bb2..4852794 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -182,8 +182,7 @@
 			srcFiles[i] = cppFile
 			genLex(ctx, srcFile, cppFile)
 		case ".proto":
-			ccFile, headerFile := genProto(ctx, srcFile, buildFlags.protoFlags,
-				buildFlags.protoOutParams, buildFlags.protoRoot)
+			ccFile, headerFile := genProto(ctx, srcFile, buildFlags)
 			srcFiles[i] = ccFile
 			deps = append(deps, headerFile)
 		case ".aidl":
diff --git a/cc/libbuildversion/libbuildversion.cpp b/cc/libbuildversion/libbuildversion.cpp
index d80d587..5242025 100644
--- a/cc/libbuildversion/libbuildversion.cpp
+++ b/cc/libbuildversion/libbuildversion.cpp
@@ -23,9 +23,19 @@
 namespace android {
 namespace build {
 
+#define PLACEHOLDER "SOONG BUILD NUMBER PLACEHOLDER"
+
+extern "C" {
+  char soong_build_number[128] = PLACEHOLDER;
+}
+
 #ifdef __ANDROID__
 
 std::string GetBuildNumber() {
+  if (strcmp(PLACEHOLDER, soong_build_number) != 0) {
+    return soong_build_number;
+  }
+
   const prop_info* pi = __system_property_find("ro.build.version.incremental");
   if (pi == nullptr) return "";
 
@@ -42,10 +52,6 @@
 
 #else
 
-extern "C" {
-  char soong_build_number[128] = "SOONG BUILD NUMBER PLACEHOLDER";
-}
-
 std::string GetBuildNumber() {
   return soong_build_number;
 }
diff --git a/cc/libbuildversion/tests/Android.bp b/cc/libbuildversion/tests/Android.bp
index a18bc6c..b3b2061 100644
--- a/cc/libbuildversion/tests/Android.bp
+++ b/cc/libbuildversion/tests/Android.bp
@@ -2,10 +2,53 @@
     name: "build_version_test_defaults",
     use_version_lib: true,
     host_supported: true,
+    dist: {
+        targets: ["test_build_version_test"],
+    },
     target: {
+        android_arm: {
+            dist: {
+                dir: "android/arm",
+            },
+        },
+        android_arm64: {
+            dist: {
+                dir: "android/arm64",
+            },
+        },
+        android_x86: {
+            dist: {
+                dir: "android/x86",
+            },
+        },
+        android_x86_64: {
+            dist: {
+                dir: "android/x86_64",
+            },
+        },
+        darwin: {
+            dist: {
+                dir: "host/",
+            },
+        },
+        linux_glibc_x86: {
+            dist: {
+                dir: "host32/",
+            },
+        },
+        linux_glibc_x86_64: {
+            dist: {
+                dir: "host/",
+            },
+        },
         windows: {
             enabled: true,
         },
+        windows_x86_64: {
+            dist: {
+                dest: "win64/build_ver_test.exe",
+            },
+        },
     },
 }
 
@@ -20,6 +63,11 @@
         not_windows: {
             shared_libs: ["libbuild_version_test"],
         },
+        host: {
+            dist: {
+                suffix: "_host",
+            },
+        },
     },
 }
 
diff --git a/cc/library.go b/cc/library.go
index 975f325..8b8fe02 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -32,19 +32,21 @@
 		Srcs   []string `android:"arch_variant"`
 		Cflags []string `android:"arch_variant"`
 
-		Enabled           *bool    `android:"arch_variant"`
-		Whole_static_libs []string `android:"arch_variant"`
-		Static_libs       []string `android:"arch_variant"`
-		Shared_libs       []string `android:"arch_variant"`
+		Enabled            *bool    `android:"arch_variant"`
+		Whole_static_libs  []string `android:"arch_variant"`
+		Static_libs        []string `android:"arch_variant"`
+		Shared_libs        []string `android:"arch_variant"`
+		System_shared_libs []string `android:"arch_variant"`
 	} `android:"arch_variant"`
 	Shared struct {
 		Srcs   []string `android:"arch_variant"`
 		Cflags []string `android:"arch_variant"`
 
-		Enabled           *bool    `android:"arch_variant"`
-		Whole_static_libs []string `android:"arch_variant"`
-		Static_libs       []string `android:"arch_variant"`
-		Shared_libs       []string `android:"arch_variant"`
+		Enabled            *bool    `android:"arch_variant"`
+		Whole_static_libs  []string `android:"arch_variant"`
+		Static_libs        []string `android:"arch_variant"`
+		Shared_libs        []string `android:"arch_variant"`
+		System_shared_libs []string `android:"arch_variant"`
 	} `android:"arch_variant"`
 
 	// local file name to pass to the linker as -unexported_symbols_list
@@ -77,6 +79,16 @@
 		// List versions to generate stubs libs for.
 		Versions []string
 	}
+
+	// set the name of the output
+	Stem *string `android:"arch_variant"`
+
+	// Names of modules to be overridden. Listed modules can only be other shared libraries
+	// (in Make or Soong).
+	// This does not completely prevent installation of the overridden libraries, but if both
+	// binaries would be installed by default (in PRODUCT_PACKAGES) the other library will be removed
+	// from PRODUCT_PACKAGES.
+	Overrides []string
 }
 
 type LibraryMutatedProperties struct {
@@ -257,6 +269,9 @@
 	// Location of the linked, unstripped library for shared libraries
 	unstrippedOutputFile android.Path
 
+	// Location of the file that should be copied to dist dir when requested
+	distFile android.OptionalPath
+
 	versionScriptPath android.ModuleGenPath
 
 	// Decorated interafaces
@@ -429,7 +444,10 @@
 func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
 	name := library.libName
 	if name == "" {
-		name = ctx.baseModuleName()
+		name = String(library.Properties.Stem)
+		if name == "" {
+			name = ctx.baseModuleName()
+		}
 	}
 
 	if ctx.isVndkExt() {
@@ -472,6 +490,16 @@
 }
 
 func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
+	if library.static() {
+		if library.Properties.Static.System_shared_libs != nil {
+			library.baseLinker.Properties.System_shared_libs = library.Properties.Static.System_shared_libs
+		}
+	} else if library.shared() {
+		if library.Properties.Shared.System_shared_libs != nil {
+			library.baseLinker.Properties.System_shared_libs = library.Properties.Shared.System_shared_libs
+		}
+	}
+
 	deps = library.baseLinker.linkerDeps(ctx, deps)
 
 	if library.static() {
@@ -529,10 +557,16 @@
 	outputFile := android.PathForModuleOut(ctx, fileName)
 	builderFlags := flagsToBuilderFlags(flags)
 
-	if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() {
-		versionedOutputFile := outputFile
-		outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
-		library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+	if Bool(library.baseLinker.Properties.Use_version_lib) {
+		if ctx.Host() {
+			versionedOutputFile := outputFile
+			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
+			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		} else {
+			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
+			library.distFile = android.OptionalPathForPath(versionedOutputFile)
+			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		}
 	}
 
 	TransformObjToStaticLib(ctx, library.objects.objFiles, builderFlags, outputFile, objs.tidyFiles)
@@ -606,10 +640,23 @@
 
 	library.unstrippedOutputFile = outputFile
 
-	if Bool(library.baseLinker.Properties.Use_version_lib) && ctx.Host() {
-		versionedOutputFile := outputFile
-		outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
-		library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+	if Bool(library.baseLinker.Properties.Use_version_lib) {
+		if ctx.Host() {
+			versionedOutputFile := outputFile
+			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
+			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		} else {
+			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
+			library.distFile = android.OptionalPathForPath(versionedOutputFile)
+
+			if library.stripper.needsStrip(ctx) {
+				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
+				library.distFile = android.OptionalPathForPath(out)
+				library.stripper.strip(ctx, versionedOutputFile, out, builderFlags)
+			}
+
+			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
+		}
 	}
 
 	sharedLibs := deps.SharedLibs
@@ -886,8 +933,19 @@
 func reuseStaticLibrary(mctx android.BottomUpMutatorContext, static, shared *Module) {
 	if staticCompiler, ok := static.compiler.(*libraryDecorator); ok {
 		sharedCompiler := shared.compiler.(*libraryDecorator)
+
+		// Check libraries in addition to cflags, since libraries may be exporting different
+		// include directories.
 		if len(staticCompiler.Properties.Static.Cflags) == 0 &&
-			len(sharedCompiler.Properties.Shared.Cflags) == 0 {
+			len(sharedCompiler.Properties.Shared.Cflags) == 0 &&
+			len(staticCompiler.Properties.Static.Whole_static_libs) == 0 &&
+			len(sharedCompiler.Properties.Shared.Whole_static_libs) == 0 &&
+			len(staticCompiler.Properties.Static.Static_libs) == 0 &&
+			len(sharedCompiler.Properties.Shared.Static_libs) == 0 &&
+			len(staticCompiler.Properties.Static.Shared_libs) == 0 &&
+			len(sharedCompiler.Properties.Shared.Shared_libs) == 0 &&
+			staticCompiler.Properties.Static.System_shared_libs == nil &&
+			sharedCompiler.Properties.Shared.System_shared_libs == nil {
 
 			mctx.AddInterVariantDependency(reuseObjTag, shared, static)
 			sharedCompiler.baseCompiler.Properties.OriginalSrcs =
diff --git a/cc/linker.go b/cc/linker.go
index a1593ee..854dfc5 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -18,6 +18,7 @@
 	"android/soong/android"
 	"android/soong/cc/config"
 	"fmt"
+	"strconv"
 
 	"github.com/google/blueprint"
 	"github.com/google/blueprint/proptools"
@@ -48,7 +49,7 @@
 	// list of system libraries that will be dynamically linked to
 	// shared library and executable modules.  If unset, generally defaults to libc,
 	// libm, and libdl.  Set to [] to prevent linking against the defaults.
-	System_shared_libs []string
+	System_shared_libs []string `android:"arch_variant"`
 
 	// allow the module to contain undefined symbols.  By default,
 	// modules cannot contain undefined symbols that are not satisified by their immediate
@@ -118,6 +119,9 @@
 			// list of runtime libs that should not be installed along with the vendor
 			// variant of the C/C++ module.
 			Exclude_runtime_libs []string
+
+			// version script for this vendor variant
+			Version_script *string `android:"arch_variant"`
 		}
 		Recovery struct {
 			// list of shared libs that only should be used to build the recovery
@@ -140,23 +144,12 @@
 
 	// make android::build:GetBuildNumber() available containing the build ID.
 	Use_version_lib *bool `android:"arch_variant"`
-}
 
-// TODO(http://b/80437643): BaseLinkerProperties is getting too big,
-// more than 2^16 bytes. New properties are defined in MoreBaseLinkerProperties.
-type MoreBaseLinkerProperties struct {
 	// Generate compact dynamic relocation table, default true.
 	Pack_relocations *bool `android:"arch_variant"`
 
 	// local file name to pass to the linker as --version_script
 	Version_script *string `android:"arch_variant"`
-
-	Target struct {
-		Vendor struct {
-			// version script for this vendor variant
-			Version_script *string `android:"arch_variant"`
-		}
-	}
 }
 
 func NewBaseLinker(sanitize *sanitize) *baseLinker {
@@ -166,7 +159,6 @@
 // baseLinker provides support for shared_libs, static_libs, and whole_static_libs properties
 type baseLinker struct {
 	Properties        BaseLinkerProperties
-	MoreProperties    MoreBaseLinkerProperties
 	dynamicProperties struct {
 		RunPaths   []string `blueprint:"mutated"`
 		BuildStubs bool     `blueprint:"mutated"`
@@ -188,7 +180,7 @@
 }
 
 func (linker *baseLinker) linkerProps() []interface{} {
-	return []interface{}{&linker.Properties, &linker.MoreProperties, &linker.dynamicProperties}
+	return []interface{}{&linker.Properties, &linker.dynamicProperties}
 }
 
 func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
@@ -245,35 +237,34 @@
 			deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
 		}
 
-		if !ctx.static() {
-			systemSharedLibs := linker.Properties.System_shared_libs
-			if systemSharedLibs == nil {
-				systemSharedLibs = []string{"libc", "libm", "libdl"}
-			}
-
-			if inList("libdl", deps.SharedLibs) {
-				// If system_shared_libs has libc but not libdl, make sure shared_libs does not
-				// have libdl to avoid loading libdl before libc.
-				if inList("libc", systemSharedLibs) {
-					if !inList("libdl", systemSharedLibs) {
-						ctx.PropertyErrorf("shared_libs",
-							"libdl must be in system_shared_libs, not shared_libs")
-					}
-					_, deps.SharedLibs = removeFromList("libdl", deps.SharedLibs)
-				}
-			}
-
-			// If libc and libdl are both in system_shared_libs make sure libd comes after libc
-			// to avoid loading libdl before libc.
-			if inList("libdl", systemSharedLibs) && inList("libc", systemSharedLibs) &&
-				indexList("libdl", systemSharedLibs) < indexList("libc", systemSharedLibs) {
-				ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc")
-			}
-
-			deps.LateSharedLibs = append(deps.LateSharedLibs, systemSharedLibs...)
-		} else if ctx.useSdk() || ctx.useVndk() {
-			deps.LateSharedLibs = append(deps.LateSharedLibs, "libc", "libm", "libdl")
+		var systemSharedLibs []string
+		if !ctx.useSdk() && !ctx.useVndk() {
+			systemSharedLibs = linker.Properties.System_shared_libs
 		}
+		if systemSharedLibs == nil {
+			systemSharedLibs = []string{"libc", "libm", "libdl"}
+		}
+
+		if inList("libdl", deps.SharedLibs) {
+			// If system_shared_libs has libc but not libdl, make sure shared_libs does not
+			// have libdl to avoid loading libdl before libc.
+			if inList("libc", systemSharedLibs) {
+				if !inList("libdl", systemSharedLibs) {
+					ctx.PropertyErrorf("shared_libs",
+						"libdl must be in system_shared_libs, not shared_libs")
+				}
+				_, deps.SharedLibs = removeFromList("libdl", deps.SharedLibs)
+			}
+		}
+
+		// If libc and libdl are both in system_shared_libs make sure libdl comes after libc
+		// to avoid loading libdl before libc.
+		if inList("libdl", systemSharedLibs) && inList("libc", systemSharedLibs) &&
+			indexList("libdl", systemSharedLibs) < indexList("libc", systemSharedLibs) {
+			ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc")
+		}
+
+		deps.LateSharedLibs = append(deps.LateSharedLibs, systemSharedLibs...)
 	}
 
 	if ctx.Windows() {
@@ -283,9 +274,9 @@
 	// Version_script is not needed when linking stubs lib where the version
 	// script is created from the symbol map file.
 	if !linker.dynamicProperties.BuildStubs {
-		android.ExtractSourceDeps(ctx, linker.MoreProperties.Version_script)
+		android.ExtractSourceDeps(ctx, linker.Properties.Version_script)
 		android.ExtractSourceDeps(ctx,
-			linker.MoreProperties.Target.Vendor.Version_script)
+			linker.Properties.Target.Vendor.Version_script)
 	}
 
 	return deps
@@ -307,6 +298,23 @@
 	return true
 }
 
+// Check whether the SDK version is not older than the specific one
+func CheckSdkVersionAtLeast(ctx ModuleContext, SdkVersion int) bool {
+	if ctx.sdkVersion() == "current" {
+		return true
+	}
+	parsedSdkVersion, err := strconv.Atoi(ctx.sdkVersion())
+	if err != nil {
+		ctx.PropertyErrorf("sdk_version",
+			"Invalid sdk_version value (must be int or current): %q",
+			ctx.sdkVersion())
+	}
+	if parsedSdkVersion < SdkVersion {
+		return false
+	}
+	return true
+}
+
 // ModuleContext extends BaseModuleContext
 // BaseModuleContext should know if LLD is used?
 func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
@@ -319,8 +327,15 @@
 
 	if linker.useClangLld(ctx) {
 		flags.LdFlags = append(flags.LdFlags, fmt.Sprintf("${config.%sGlobalLldflags}", hod))
-		if !BoolDefault(linker.MoreProperties.Pack_relocations, true) {
+		if !BoolDefault(linker.Properties.Pack_relocations, true) {
 			flags.LdFlags = append(flags.LdFlags, "-Wl,--pack-dyn-relocs=none")
+		} else if ctx.Device() {
+			// The SHT_RELR relocations is only supported by API level >= 28.
+			// Do not turn this on if older version NDK is used.
+			if !ctx.useSdk() || CheckSdkVersionAtLeast(ctx, 28) {
+				flags.LdFlags = append(flags.LdFlags, "-Wl,--pack-dyn-relocs=android+relr")
+				flags.LdFlags = append(flags.LdFlags, "-Wl,--use-android-relr-tags")
+			}
 		}
 	} else {
 		flags.LdFlags = append(flags.LdFlags, fmt.Sprintf("${config.%sGlobalLdflags}", hod))
@@ -394,11 +409,11 @@
 	// script is created from the symbol map file.
 	if !linker.dynamicProperties.BuildStubs {
 		versionScript := ctx.ExpandOptionalSource(
-			linker.MoreProperties.Version_script, "version_script")
+			linker.Properties.Version_script, "version_script")
 
-		if ctx.useVndk() && linker.MoreProperties.Target.Vendor.Version_script != nil {
+		if ctx.useVndk() && linker.Properties.Target.Vendor.Version_script != nil {
 			versionScript = ctx.ExpandOptionalSource(
-				linker.MoreProperties.Target.Vendor.Version_script,
+				linker.Properties.Target.Vendor.Version_script,
 				"target.vendor.version_script")
 		}
 
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 8177ff1..504a6a0 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -77,6 +77,11 @@
 
 	// Path to the NOTICE file associated with the headers.
 	License *string
+
+	// True if this API is not yet ready to be shipped in the NDK. It will be
+	// available in the platform for testing, but will be excluded from the
+	// sysroot provided to the NDK proper.
+	Draft bool
 }
 
 type headerModule struct {
@@ -182,6 +187,11 @@
 
 	// Path to the NOTICE file associated with the headers.
 	License *string
+
+	// True if this API is not yet ready to be shipped in the NDK. It will be
+	// available in the platform for testing, but will be excluded from the
+	// sysroot provided to the NDK proper.
+	Draft bool
 }
 
 // Like ndk_headers, but preprocesses the headers with the bionic versioner:
@@ -309,6 +319,11 @@
 
 	// Path to the NOTICE file associated with the headers.
 	License *string
+
+	// True if this API is not yet ready to be shipped in the NDK. It will be
+	// available in the platform for testing, but will be excluded from the
+	// sysroot provided to the NDK proper.
+	Draft bool
 }
 
 type preprocessedHeadersModule struct {
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 63d9f29..53fe314 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -91,6 +91,11 @@
 
 	// Private property for use by the mutator that splits per-API level.
 	ApiLevel string `blueprint:"mutated"`
+
+	// True if this API is not yet ready to be shipped in the NDK. It will be
+	// available in the platform for testing, but will be excluded from the
+	// sysroot provided to the NDK proper.
+	Draft bool
 }
 
 type stubDecorator struct {
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 80b5c6a..9265bff 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -104,22 +104,38 @@
 		}
 
 		if m, ok := module.(*headerModule); ok {
+			if ctx.Config().ExcludeDraftNdkApis() && m.properties.Draft {
+				return
+			}
+
 			installPaths = append(installPaths, m.installPaths...)
 			licensePaths = append(licensePaths, m.licensePath)
 		}
 
 		if m, ok := module.(*versionedHeaderModule); ok {
+			if ctx.Config().ExcludeDraftNdkApis() && m.properties.Draft {
+				return
+			}
+
 			installPaths = append(installPaths, m.installPaths...)
 			licensePaths = append(licensePaths, m.licensePath)
 		}
 
 		if m, ok := module.(*preprocessedHeadersModule); ok {
+			if ctx.Config().ExcludeDraftNdkApis() && m.properties.Draft {
+				return
+			}
+
 			installPaths = append(installPaths, m.installPaths...)
 			licensePaths = append(licensePaths, m.licensePath)
 		}
 
 		if m, ok := module.(*Module); ok {
 			if installer, ok := m.installer.(*stubDecorator); ok {
+				if ctx.Config().ExcludeDraftNdkApis() &&
+					installer.properties.Draft {
+					return
+				}
 				installPaths = append(installPaths, installer.installPath)
 			}
 
diff --git a/cc/proto.go b/cc/proto.go
index 6e6f95e..61fd607 100644
--- a/cc/proto.go
+++ b/cc/proto.go
@@ -31,41 +31,56 @@
 var (
 	proto = pctx.AndroidStaticRule("protoc",
 		blueprint.RuleParams{
-			Command: "$protocCmd --cpp_out=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " +
+			Command: "$protocCmd $protoOut=$protoOutParams:$outDir --dependency_out=$out.d -I $protoBase $protoFlags $in && " +
 				`$depFixCmd $out.d`,
 			CommandDeps: []string{"$protocCmd", "$depFixCmd"},
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
-		}, "protoFlags", "protoOutParams", "protoBase", "outDir")
+		}, "protoFlags", "protoOut", "protoOutParams", "protoBase", "outDir")
 )
 
 // genProto creates a rule to convert a .proto file to generated .pb.cc and .pb.h files and returns
 // the paths to the generated files.
-func genProto(ctx android.ModuleContext, protoFile android.Path,
-	protoFlags, protoOutParams string, root bool) (ccFile, headerFile android.WritablePath) {
+func genProto(ctx android.ModuleContext, protoFile android.Path, flags builderFlags) (ccFile, headerFile android.WritablePath) {
+
+	srcSuffix := ".cc"
+	if flags.protoC {
+		srcSuffix = ".c"
+	}
 
 	var protoBase string
-	if root {
+	if flags.protoRoot {
 		protoBase = "."
-		ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.cc")
+		ccFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb"+srcSuffix)
 		headerFile = android.GenPathWithExt(ctx, "proto", protoFile, "pb.h")
 	} else {
 		rel := protoFile.Rel()
 		protoBase = strings.TrimSuffix(protoFile.String(), rel)
-		ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.cc"))
+		ccFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb"+srcSuffix))
 		headerFile = android.PathForModuleGen(ctx, "proto", pathtools.ReplaceExtension(rel, "pb.h"))
 	}
 
+	protoDeps := flags.protoDeps
+	if flags.protoOptionsFile {
+		optionsFile := pathtools.ReplaceExtension(protoFile.String(), "options")
+		optionsPath := android.ExistentPathForSource(ctx, optionsFile)
+		if optionsPath.Valid() {
+			protoDeps = append(android.Paths{optionsPath.Path()}, protoDeps...)
+		}
+	}
+
 	ctx.Build(pctx, android.BuildParams{
 		Rule:           proto,
 		Description:    "protoc " + protoFile.Rel(),
 		Output:         ccFile,
 		ImplicitOutput: headerFile,
 		Input:          protoFile,
+		Implicits:      protoDeps,
 		Args: map[string]string{
 			"outDir":         android.ProtoDir(ctx).String(),
-			"protoFlags":     protoFlags,
-			"protoOutParams": protoOutParams,
+			"protoFlags":     flags.protoFlags,
+			"protoOut":       flags.protoOutTypeFlag,
+			"protoOutParams": flags.protoOutParams,
 			"protoBase":      protoBase,
 		},
 	})
@@ -91,6 +106,12 @@
 		} else {
 			lib = "libprotobuf-cpp-lite"
 		}
+	case "nanopb-c":
+		lib = "libprotobuf-c-nano"
+		static = true
+	case "nanopb-c-enable_malloc":
+		lib = "libprotobuf-c-nano-enable_malloc"
+		static = true
 	default:
 		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
 			String(p.Proto.Type))
@@ -118,8 +139,33 @@
 
 	flags.protoFlags = android.ProtoFlags(ctx, p)
 
-	if String(p.Proto.Type) == "lite" {
+	var plugin string
+
+	switch String(p.Proto.Type) {
+	case "nanopb-c", "nanopb-c-enable_malloc":
+		flags.protoC = true
+		flags.protoOptionsFile = true
+		flags.protoOutTypeFlag = "--nanopb_out"
+		plugin = "protoc-gen-nanopb"
+	case "full":
+		flags.protoOutTypeFlag = "--cpp_out"
+	case "lite":
+		flags.protoOutTypeFlag = "--cpp_out"
 		flags.protoOutParams = append(flags.protoOutParams, "lite")
+	case "":
+		// TODO(b/119714316): this should be equivalent to "lite" in
+		// order to match protoDeps, but some modules are depending on
+		// this behavior
+		flags.protoOutTypeFlag = "--cpp_out"
+	default:
+		ctx.PropertyErrorf("proto.type", "unknown proto type %q",
+			String(p.Proto.Type))
+	}
+
+	if plugin != "" {
+		path := ctx.Config().HostToolPath(ctx, plugin)
+		flags.protoDeps = append(flags.protoDeps, path)
+		flags.protoFlags = append(flags.protoFlags, "--plugin="+path.String())
 	}
 
 	return flags
diff --git a/cc/rs.go b/cc/rs.go
index 7c9f5d3..5421b92 100644
--- a/cc/rs.go
+++ b/cc/rs.go
@@ -16,13 +16,22 @@
 
 import (
 	"android/soong/android"
+	"path/filepath"
+	"runtime"
 	"strings"
 
 	"github.com/google/blueprint"
 )
 
 func init() {
-	pctx.HostBinToolVariable("rsCmd", "llvm-rs-cc")
+	pctx.VariableFunc("rsCmd", func(ctx android.PackageVarContext) string {
+		if ctx.Config().UnbundledBuild() {
+			// Use RenderScript prebuilts for unbundled builds but not PDK builds
+			return filepath.Join("prebuilts/sdk/tools", runtime.GOOS, "bin/llvm-rs-cc")
+		} else {
+			return pctx.HostBinToolPath(ctx, "llvm-rs-cc").String()
+		}
+	})
 }
 
 var rsCppCmdLine = strings.Replace(`
diff --git a/cc/sanitize.go b/cc/sanitize.go
index cd3b3e9..56013b6 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -49,8 +49,14 @@
 	cfiStaticLibsMutex    sync.Mutex
 	hwasanStaticLibsMutex sync.Mutex
 
-	intOverflowCflags   = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
-	minimalRuntimeFlags = []string{"-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
+	intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
+
+	// Pass -Xclang before -fsanitize-minimal-runtime to work around a driver
+	// check which rejects -fsanitize-minimal-runtime together with
+	// -fsanitize=shadow-call-stack even though this combination of flags
+	// is valid.
+	// TODO(pcc): Remove the -Xclang once LLVM r346526 is rolled into the compiler.
+	minimalRuntimeFlags = []string{"-Xclang", "-fsanitize-minimal-runtime", "-fno-sanitize-trap=integer,undefined",
 		"-fno-sanitize-recover=integer,undefined"}
 	hwasanGlobalOptions = []string{"heap_history_size=4095"}
 )
@@ -71,6 +77,7 @@
 	tsan
 	intOverflow
 	cfi
+	scs
 )
 
 func (t sanitizerType) String() string {
@@ -85,6 +92,8 @@
 		return "intOverflow"
 	case cfi:
 		return "cfi"
+	case scs:
+		return "scs"
 	default:
 		panic(fmt.Errorf("unknown sanitizerType %d", t))
 	}
@@ -109,6 +118,7 @@
 		Cfi              *bool    `android:"arch_variant"`
 		Integer_overflow *bool    `android:"arch_variant"`
 		Scudo            *bool    `android:"arch_variant"`
+		Scs              *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.
@@ -276,6 +286,14 @@
 		s.Hwaddress = nil
 	}
 
+	// SCS is only implemented on AArch64.
+	// We also disable SCS if ASAN, TSAN or HWASAN are enabled because Clang considers
+	// them to be incompatible, although they are in fact compatible.
+	// TODO(pcc): Remove these checks once r347282 is rolled into the compiler.
+	if ctx.Arch().ArchType != android.Arm64 || Bool(s.Address) || Bool(s.Thread) || Bool(s.Hwaddress) {
+		s.Scs = nil
+	}
+
 	// Also disable CFI if ASAN is enabled.
 	if Bool(s.Address) || Bool(s.Hwaddress) {
 		s.Cfi = nil
@@ -299,7 +317,8 @@
 	}
 
 	// HWASan ramdisk (which is built from recovery) goes over some bootloader limit.
-	if ctx.inRecovery() {
+	// Keep libc instrumented so that recovery can run hwasan-instrumented code if necessary.
+	if ctx.inRecovery() && !strings.HasPrefix(ctx.ModuleDir(), "bionic/libc") {
 		s.Hwaddress = nil
 	}
 
@@ -322,7 +341,7 @@
 
 	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.Scudo) || Bool(s.Hwaddress)) {
+		Bool(s.Scudo) || Bool(s.Hwaddress) || Bool(s.Scs)) {
 		sanitize.Properties.SanitizerEnabled = true
 	}
 
@@ -490,6 +509,10 @@
 		sanitizers = append(sanitizers, "scudo")
 	}
 
+	if Bool(sanitize.Properties.Sanitize.Scs) {
+		sanitizers = append(sanitizers, "shadow-call-stack")
+	}
+
 	if len(sanitizers) > 0 {
 		sanitizeArg := "-fsanitize=" + strings.Join(sanitizers, ",")
 
@@ -553,9 +576,12 @@
 		sanitize.runtimeLibrary = runtimeLibrary
 
 		// When linking against VNDK, use the vendor variant of the runtime lib
-		sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary
 		if ctx.useVndk() {
 			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary + vendorSuffix
+		} else if ctx.inRecovery() {
+			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary + recoverySuffix
+		} else {
+			sanitize.androidMkRuntimeLibrary = sanitize.runtimeLibrary
 		}
 	}
 
@@ -583,6 +609,9 @@
 	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Hwaddress) {
 		ret.SubName += ".hwasan"
 	}
+	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Scs) {
+		ret.SubName += ".scs"
+	}
 }
 
 func (sanitize *sanitize) inSanitizerDir() bool {
@@ -601,6 +630,8 @@
 		return sanitize.Properties.Sanitize.Integer_overflow
 	case cfi:
 		return sanitize.Properties.Sanitize.Cfi
+	case scs:
+		return sanitize.Properties.Sanitize.Scs
 	default:
 		panic(fmt.Errorf("unknown sanitizerType %d", t))
 	}
@@ -610,7 +641,8 @@
 	return !sanitize.isSanitizerEnabled(asan) &&
 		!sanitize.isSanitizerEnabled(hwasan) &&
 		!sanitize.isSanitizerEnabled(tsan) &&
-		!sanitize.isSanitizerEnabled(cfi)
+		!sanitize.isSanitizerEnabled(cfi) &&
+		!sanitize.isSanitizerEnabled(scs)
 }
 
 func (sanitize *sanitize) isVariantOnProductionDevice() bool {
@@ -634,6 +666,8 @@
 		sanitize.Properties.Sanitize.Integer_overflow = boolPtr(b)
 	case cfi:
 		sanitize.Properties.Sanitize.Cfi = boolPtr(b)
+	case scs:
+		sanitize.Properties.Sanitize.Scs = boolPtr(b)
 	default:
 		panic(fmt.Errorf("unknown sanitizerType %d", t))
 	}
@@ -683,7 +717,7 @@
 				if d, ok := child.(*Module); ok && d.sanitize != nil &&
 					!Bool(d.sanitize.Properties.Sanitize.Never) &&
 					!d.sanitize.isSanitizerExplicitlyDisabled(t) {
-					if t == cfi || t == hwasan {
+					if t == cfi || t == hwasan || t == scs {
 						if d.static() {
 							d.sanitize.Properties.SanitizeDep = true
 						}
@@ -779,6 +813,19 @@
 						modules[1].(*Module).Properties.PreventInstall = true
 						modules[1].(*Module).Properties.HideFromMake = true
 					}
+				} else if t == scs {
+					// We don't currently link any static libraries built with make into
+					// libraries built with SCS, so we don't need logic for propagating
+					// SCSness of dependencies into make.
+					if !c.static() {
+						if isSanitizerEnabled {
+							modules[0].(*Module).Properties.PreventInstall = true
+							modules[0].(*Module).Properties.HideFromMake = true
+						} else {
+							modules[1].(*Module).Properties.PreventInstall = true
+							modules[1].(*Module).Properties.HideFromMake = true
+						}
+					}
 				} else if t == hwasan {
 					if mctx.Device() {
 						// CFI and HWASAN are currently mutually exclusive so disable
diff --git a/cc/stl.go b/cc/stl.go
index 8eee612..4870870 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -17,6 +17,7 @@
 import (
 	"android/soong/android"
 	"fmt"
+	"strconv"
 )
 
 func getNdkStlFamily(m *Module) string {
@@ -110,6 +111,26 @@
 	}()
 }
 
+func needsLibAndroidSupport(ctx BaseModuleContext) bool {
+	versionStr, err := normalizeNdkApiLevel(ctx, ctx.sdkVersion(), ctx.Arch())
+	if err != nil {
+		ctx.PropertyErrorf("sdk_version", err.Error())
+	}
+
+	if versionStr == "current" {
+		return false
+	}
+
+	version, err := strconv.Atoi(versionStr)
+	if err != nil {
+		panic(fmt.Sprintf(
+			"invalid API level returned from normalizeNdkApiLevel: %q",
+			versionStr))
+	}
+
+	return version < 21
+}
+
 func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps {
 	switch stl.Properties.SelectedStl {
 	case "libstdc++":
@@ -141,7 +162,9 @@
 		} else {
 			deps.StaticLibs = append(deps.StaticLibs, stl.Properties.SelectedStl, "ndk_libc++abi")
 		}
-		deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
+		if needsLibAndroidSupport(ctx) {
+			deps.StaticLibs = append(deps.StaticLibs, "ndk_libandroid_support")
+		}
 		if ctx.Arch().ArchType == android.Arm {
 			deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind")
 		}
@@ -228,7 +251,7 @@
 		android.Linux:  []string{"-lgcc_s", "-lgcc", "-lc", "-lgcc_s", "-lgcc"},
 		android.Darwin: []string{"-lc", "-lSystem"},
 		android.Windows: []string{"-Wl,--start-group", "-lmingw32", "-lgcc", "-lgcc_eh",
-			"-lmoldname", "-lmingwex", "-lmsvcr110", "-lmsvcrt", "-lpthread",
+			"-lmoldname", "-lmingwex", "-lmsvcrt", "-lucrt", "-lpthread",
 			"-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lpsapi",
 			"-Wl,--end-group"},
 	}
diff --git a/cc/test.go b/cc/test.go
index 96049db..f7180b5 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -16,7 +16,6 @@
 
 import (
 	"path/filepath"
-	"runtime"
 	"strings"
 
 	"android/soong/android"
@@ -377,16 +376,6 @@
 }
 
 func NewBenchmark(hod android.HostOrDeviceSupported) *Module {
-	// Benchmarks aren't supported on Darwin
-	if runtime.GOOS == "darwin" {
-		switch hod {
-		case android.HostAndDeviceSupported:
-			hod = android.DeviceSupported
-		case android.HostSupported:
-			hod = android.NeitherHostNorDeviceSupported
-		}
-	}
-
 	module, binary := NewBinary(hod)
 	module.multilib = android.MultilibBoth
 	binary.baseInstaller = NewBaseInstaller("benchmarktest", "benchmarktest64", InstallInData)
diff --git a/cc/util.go b/cc/util.go
index c900423..925dd74 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -68,8 +68,6 @@
 		conlyFlags:      strings.Join(in.ConlyFlags, " "),
 		cppFlags:        strings.Join(in.CppFlags, " "),
 		yaccFlags:       strings.Join(in.YaccFlags, " "),
-		protoFlags:      strings.Join(in.protoFlags, " "),
-		protoOutParams:  strings.Join(in.protoOutParams, ","),
 		aidlFlags:       strings.Join(in.aidlFlags, " "),
 		rsFlags:         strings.Join(in.rsFlags, " "),
 		ldFlags:         strings.Join(in.LdFlags, " "),
@@ -81,11 +79,18 @@
 		coverage:        in.Coverage,
 		tidy:            in.Tidy,
 		sAbiDump:        in.SAbiDump,
-		protoRoot:       in.ProtoRoot,
 
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
 
 		groupStaticLibs: in.GroupStaticLibs,
+
+		protoDeps:        in.protoDeps,
+		protoFlags:       strings.Join(in.protoFlags, " "),
+		protoOutTypeFlag: in.protoOutTypeFlag,
+		protoOutParams:   strings.Join(in.protoOutParams, ","),
+		protoC:           in.protoC,
+		protoOptionsFile: in.protoOptionsFile,
+		protoRoot:        in.ProtoRoot,
 	}
 }
 
diff --git a/cc/xom.go b/cc/xom.go
new file mode 100644
index 0000000..182069f
--- /dev/null
+++ b/cc/xom.go
@@ -0,0 +1,76 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import (
+	"android/soong/android"
+)
+
+type XomProperties struct {
+	Xom *bool
+}
+
+type xom struct {
+	Properties XomProperties
+}
+
+func (xom *xom) props() []interface{} {
+	return []interface{}{&xom.Properties}
+}
+
+func (xom *xom) begin(ctx BaseModuleContext) {}
+
+func (xom *xom) deps(ctx BaseModuleContext, deps Deps) Deps {
+	return deps
+}
+
+func (xom *xom) flags(ctx ModuleContext, flags Flags) Flags {
+	disableXom := false
+
+	if !ctx.Config().EnableXOM() || ctx.Config().XOMDisabledForPath(ctx.ModuleDir()) {
+		disableXom = true
+	}
+
+	if xom.Properties.Xom != nil && !*xom.Properties.Xom {
+		return flags
+	}
+
+	// If any static dependencies have XOM disabled, we should disable XOM in this module,
+	// the assumption being if it's been explicitly disabled then there's probably incompatible
+	// code in the library which may get pulled in.
+	if !ctx.static() && !disableXom {
+		ctx.VisitDirectDeps(func(m android.Module) {
+			cc, ok := m.(*Module)
+			if !ok || cc.xom == nil || !cc.static() {
+				return
+			}
+			if cc.xom.Properties.Xom != nil && !*cc.xom.Properties.Xom {
+				disableXom = true
+				return
+			}
+		})
+	}
+
+	// Enable execute-only if none of the dependencies disable it,
+	// also if it's explicitly set true (allows overriding dependencies disabling it).
+	if !disableXom || (xom.Properties.Xom != nil && *xom.Properties.Xom) {
+		// XOM is only supported on AArch64 when using lld.
+		if ctx.Arch().ArchType == android.Arm64 && ctx.useClangLld(ctx) {
+			flags.LdFlags = append(flags.LdFlags, "-Wl,-execute-only")
+		}
+	}
+
+	return flags
+}
diff --git a/cmd/host_bionic_inject/Android.bp b/cmd/host_bionic_inject/Android.bp
index acce683..5994103 100644
--- a/cmd/host_bionic_inject/Android.bp
+++ b/cmd/host_bionic_inject/Android.bp
@@ -16,4 +16,5 @@
     name: "host_bionic_inject",
     deps: ["soong-symbol_inject"],
     srcs: ["host_bionic_inject.go"],
+    testSrcs: ["host_bionic_inject_test.go"],
 }
diff --git a/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_inject/host_bionic_inject.go
index 0dabbba..f7163d7 100644
--- a/cmd/host_bionic_inject/host_bionic_inject.go
+++ b/cmd/host_bionic_inject/host_bionic_inject.go
@@ -136,33 +136,28 @@
 			continue
 		}
 
+		laddr := lprog.Vaddr + dlwrap_linker_offset.Value
+
 		found := false
-		for j, prog := range file.Progs {
+		for _, prog := range file.Progs {
 			if prog.Type != elf.PT_LOAD {
 				continue
 			}
 
-			if lprog.Vaddr+dlwrap_linker_offset.Value != prog.Vaddr {
+			if laddr < prog.Vaddr || laddr > prog.Vaddr+prog.Memsz {
 				continue
 			}
 			found = true
 
-			if lprog.Memsz != prog.Memsz {
-				return fmt.Errorf("Linker prog %d (0x%x) memsz (0x%x) does not match (0x%x)",
-					i, lprog.Vaddr, lprog.Memsz, prog.Memsz)
-			}
-
-			// The linker shouldn't be using BSS, since only one
-			// BSS section is supported per ELF file.
-			if prog.Memsz != prog.Filesz {
-				return fmt.Errorf("Embedded prog %d (0x%x) memsz (0x%x) does not match filesz (0x%x)",
-					j, prog.Vaddr, prog.Memsz, prog.Filesz)
-			}
-
 			if lprog.Flags != prog.Flags {
 				return fmt.Errorf("Linker prog %d (0x%x) flags (%s) do not match (%s)",
 					i, lprog.Vaddr, lprog.Flags, prog.Flags)
 			}
+
+			if laddr+lprog.Memsz > prog.Vaddr+prog.Filesz {
+				return fmt.Errorf("Linker prog %d (0x%x) not fully present (0x%x > 0x%x)",
+					i, lprog.Vaddr, laddr+lprog.Memsz, prog.Vaddr+prog.Filesz)
+			}
 		}
 		if !found {
 			return fmt.Errorf("Linker prog %d (0x%x) not found at offset 0x%x",
diff --git a/cmd/host_bionic_inject/host_bionic_inject_test.go b/cmd/host_bionic_inject/host_bionic_inject_test.go
new file mode 100644
index 0000000..b415b34
--- /dev/null
+++ b/cmd/host_bionic_inject/host_bionic_inject_test.go
@@ -0,0 +1,146 @@
+// Copyright 2018 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+	"debug/elf"
+	"fmt"
+	"testing"
+)
+
+// prog is a shortcut to fill out a elf.Prog structure
+func prog(flags elf.ProgFlag, offset, addr, filesz, memsz uint64) *elf.Prog {
+	return &elf.Prog{
+		ProgHeader: elf.ProgHeader{
+			Type:   elf.PT_LOAD,
+			Flags:  flags,
+			Off:    offset,
+			Vaddr:  addr,
+			Paddr:  addr,
+			Filesz: filesz,
+			Memsz:  memsz,
+		},
+	}
+}
+
+// linkerGold returns an example elf.File from a linker binary that was linked
+// with gold.
+func linkerGold() *elf.File {
+	return &elf.File{
+		Progs: []*elf.Prog{
+			prog(elf.PF_R|elf.PF_X, 0, 0, 0xd0fac, 0xd0fac),
+			prog(elf.PF_R|elf.PF_W, 0xd1050, 0xd2050, 0x6890, 0xd88c),
+		},
+	}
+}
+
+// fileGold returns an example elf binary with a properly embedded linker. The
+// embedded linker was the one returned by linkerGold.
+func fileGold() *elf.File {
+	return &elf.File{
+		Progs: []*elf.Prog{
+			prog(elf.PF_R, 0, 0, 0x2e0, 0x2e0),
+			prog(elf.PF_R|elf.PF_X, 0x1000, 0x1000, 0xd0fac, 0xd0fac),
+			prog(elf.PF_R|elf.PF_W, 0xd2050, 0xd3050, 0xd88c, 0xd88c),
+			prog(elf.PF_R, 0xe0000, 0xe1000, 0x10e4, 0x10e4),
+			prog(elf.PF_R|elf.PF_X, 0xe2000, 0xe3000, 0x1360, 0x1360),
+			prog(elf.PF_R|elf.PF_W, 0xe4000, 0xe5000, 0x1358, 0x1358),
+		},
+	}
+}
+
+// linkerLld returns an example elf.File from a linker binary that was linked
+// with lld.
+func linkerLld() *elf.File {
+	return &elf.File{
+		Progs: []*elf.Prog{
+			prog(elf.PF_R, 0, 0, 0x3c944, 0x3c944),
+			prog(elf.PF_R|elf.PF_X, 0x3d000, 0x3d000, 0x946fa, 0x946fa),
+			prog(elf.PF_R|elf.PF_W, 0xd2000, 0xd2000, 0x7450, 0xf778),
+		},
+	}
+}
+
+// fileGold returns an example elf binary with a properly embedded linker. The
+// embedded linker was the one returned by linkerLld.
+func fileLld() *elf.File {
+	return &elf.File{
+		Progs: []*elf.Prog{
+			prog(elf.PF_R, 0, 0, 0x3d944, 0x3d944),
+			prog(elf.PF_R|elf.PF_X, 0x3e000, 0x3e000, 0x946fa, 0x946fa),
+			prog(elf.PF_R|elf.PF_W, 0xd3000, 0xd3000, 0xf778, 0xf778),
+			prog(elf.PF_R, 0xe3000, 0xe3000, 0x10e4, 0x10e4),
+			prog(elf.PF_R|elf.PF_X, 0xe5000, 0xe5000, 0x1360, 0x1360),
+			prog(elf.PF_R|elf.PF_W, 0xe7000, 0xe7000, 0x1358, 0x1358),
+		},
+	}
+}
+
+// linkerOffset returns the symbol representing the linker offset used by both
+// fileGold and fileLld
+func linkerOffset() []elf.Symbol {
+	return []elf.Symbol{
+		elf.Symbol{
+			Name:  "__dlwrap_linker_offset",
+			Value: 0x1000,
+		},
+	}
+}
+
+func TestCheckLinker(t *testing.T) {
+	cases := []struct {
+		name   string
+		err    error
+		file   func() *elf.File
+		linker func() *elf.File
+	}{
+		{
+			name:   "good gold-linked linker",
+			file:   fileGold,
+			linker: linkerGold,
+		},
+		{
+			name:   "good lld-linked linker",
+			file:   fileLld,
+			linker: linkerLld,
+		},
+		{
+			name: "truncated RO section",
+			err:  fmt.Errorf("Linker prog 0 (0x0) not fully present (0x3d944 > 0x3d943)"),
+			file: func() *elf.File {
+				f := fileLld()
+				f.Progs[0].Filesz -= 1
+				f.Progs[0].Memsz -= 1
+				return f
+			},
+			linker: linkerLld,
+		},
+	}
+
+	for _, tc := range cases {
+		t.Run(tc.name, func(t *testing.T) {
+			err := checkLinker(tc.file(), tc.linker(), linkerOffset())
+			if tc.err == nil {
+				if err != nil {
+					t.Fatalf("No error expected, but got: %v", err)
+				}
+			} else if err == nil {
+				t.Fatalf("Returned no error, but wanted: %v", tc.err)
+			} else if err.Error() != tc.err.Error() {
+				t.Fatalf("Different error found:\nwant: %v\n got: %v", tc.err, err)
+			}
+		})
+	}
+}
diff --git a/cmd/merge_zips/merge_zips.go b/cmd/merge_zips/merge_zips.go
index 8e71a97..c21da44 100644
--- a/cmd/merge_zips/merge_zips.go
+++ b/cmd/merge_zips/merge_zips.go
@@ -19,6 +19,7 @@
 	"flag"
 	"fmt"
 	"hash/crc32"
+	"io"
 	"io/ioutil"
 	"log"
 	"os"
@@ -66,6 +67,7 @@
 	manifest         = flag.String("m", "", "manifest file to insert in jar")
 	pyMain           = flag.String("pm", "", "__main__.py file to insert in par")
 	entrypoint       = flag.String("e", "", "par entrypoint file to insert in par")
+	prefix           = flag.String("prefix", "", "A file to prefix to the zip file")
 	ignoreDuplicates = flag.Bool("ignore-duplicates", false, "take each entry from the first zip it exists in and don't warn")
 )
 
@@ -77,7 +79,7 @@
 
 func main() {
 	flag.Usage = func() {
-		fmt.Fprintln(os.Stderr, "usage: merge_zips [-jpsD] [-m manifest] [-e entrypoint] [-pm __main__.py] output [inputs...]")
+		fmt.Fprintln(os.Stderr, "usage: merge_zips [-jpsD] [-m manifest] [--prefix script] [-e entrypoint] [-pm __main__.py] output [inputs...]")
 		flag.PrintDefaults()
 	}
 
@@ -99,6 +101,19 @@
 		log.Fatal(err)
 	}
 	defer output.Close()
+
+	var offset int64
+	if *prefix != "" {
+		prefixFile, err := os.Open(*prefix)
+		if err != nil {
+			log.Fatal(err)
+		}
+		offset, err = io.Copy(output, prefixFile)
+		if err != nil {
+			log.Fatal(err)
+		}
+	}
+
 	writer := zip.NewWriter(output)
 	defer func() {
 		err := writer.Close()
@@ -106,6 +121,7 @@
 			log.Fatal(err)
 		}
 	}()
+	writer.SetOffset(offset)
 
 	// make readers
 	readers := []namedZipReader{}
diff --git a/java/aar.go b/java/aar.go
index a49aef0..99e9136 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -157,11 +157,9 @@
 }
 
 func (a *aapt) deps(ctx android.BottomUpMutatorContext, sdkContext sdkContext) {
-	if !ctx.Config().UnbundledBuild() {
-		sdkDep := decodeSdkDep(ctx, sdkContext)
-		if sdkDep.frameworkResModule != "" {
-			ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
-		}
+	sdkDep := decodeSdkDep(ctx, sdkContext)
+	if sdkDep.frameworkResModule != "" {
+		ctx.AddVariationDependencies(nil, frameworkResTag, sdkDep.frameworkResModule)
 	}
 }
 
diff --git a/java/app_builder.go b/java/app_builder.go
index b0983bd..28fc4c4 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -32,10 +32,10 @@
 	Signapk = pctx.AndroidStaticRule("signapk",
 		blueprint.RuleParams{
 			Command: `${config.JavaCmd} -Djava.library.path=$$(dirname $signapkJniLibrary) ` +
-				`-jar $signapkCmd $certificates $in $out`,
+				`-jar $signapkCmd $flags $certificates $in $out`,
 			CommandDeps: []string{"$signapkCmd", "$signapkJniLibrary"},
 		},
-		"certificates")
+		"flags", "certificates")
 
 	androidManifestMerger = pctx.AndroidStaticRule("androidManifestMerger",
 		blueprint.RuleParams{
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index 35f9e9d..432840e 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -15,7 +15,11 @@
 package config
 
 var (
-	KotlinStdlibJar = "external/kotlinc/lib/kotlin-stdlib.jar"
+	KotlinStdlibJar     = "external/kotlinc/lib/kotlin-stdlib.jar"
+	KotlincIllegalFlags = []string{
+		"-no-jdk",
+		"-no-stdlib",
+	}
 )
 
 func init() {
diff --git a/java/dex.go b/java/dex.go
index 5cec325..a6d486a 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -160,6 +160,11 @@
 	// TODO(ccross): if this is an instrumentation test of an obfuscated app, use the
 	// dictionary of the app and move the app from libraryjars to injars.
 
+	// Don't strip out debug information for eng builds.
+	if ctx.Config().Eng() {
+		r8Flags = append(r8Flags, "--debug")
+	}
+
 	return r8Flags, r8Deps
 }
 
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 9dadb30..9cde189 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -360,6 +360,9 @@
 	// a list of top-level directories containing Java stub files to merge show/hide annotations from.
 	Merge_inclusion_annotations_dirs []string
 
+	// a file containing a list of classes to do nullability validation for.
+	Validate_nullability_from_list *string
+
 	// a file containing expected warnings produced by validation of nullability annotations.
 	Check_nullability_warnings *string
 
@@ -1126,9 +1129,9 @@
 		Inputs:      d.Javadoc.srcFiles,
 		Implicits:   implicits,
 		Args: map[string]string{
-			"outDir":        android.PathForModuleOut(ctx, "out").String(),
-			"srcJarDir":     android.PathForModuleOut(ctx, "srcjars").String(),
-			"stubsDir":      android.PathForModuleOut(ctx, "stubsDir").String(),
+			"outDir":        android.PathForModuleOut(ctx, "dokka-out").String(),
+			"srcJarDir":     android.PathForModuleOut(ctx, "dokka-srcjars").String(),
+			"stubsDir":      android.PathForModuleOut(ctx, "dokka-stubsDir").String(),
 			"srcJars":       strings.Join(d.Javadoc.srcJars.Strings(), " "),
 			"classpathArgs": classpathArgs,
 			"opts":          opts,
@@ -1302,6 +1305,9 @@
 		}
 	}
 
+	if String(d.properties.Validate_nullability_from_list) != "" {
+		android.ExtractSourceDeps(ctx, d.properties.Validate_nullability_from_list)
+	}
 	if String(d.properties.Check_nullability_warnings) != "" {
 		android.ExtractSourceDeps(ctx, d.properties.Check_nullability_warnings)
 	}
@@ -1411,7 +1417,9 @@
 	var flags string
 	if Bool(d.properties.Annotations_enabled) {
 		flags += " --include-annotations"
-		validatingNullability := strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs")
+		validatingNullability :=
+			strings.Contains(d.Javadoc.args, "--validate-nullability-from-merged-stubs") ||
+				String(d.properties.Validate_nullability_from_list) != ""
 		migratingNullability := String(d.properties.Previous_api) != ""
 		if !(migratingNullability || validatingNullability) {
 			ctx.PropertyErrorf("previous_api",
@@ -1422,6 +1430,9 @@
 			*implicits = append(*implicits, previousApi)
 			flags += " --migrate-nullness " + previousApi.String()
 		}
+		if s := String(d.properties.Validate_nullability_from_list); s != "" {
+			flags += " --validate-nullability-from-list " + ctx.ExpandSource(s, "validate_nullability_from_list").String()
+		}
 		if validatingNullability {
 			d.nullabilityWarningsFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"_nullability_warnings.txt")
 			*implicitOutputs = append(*implicitOutputs, d.nullabilityWarningsFile)
@@ -1574,7 +1585,7 @@
 		Implicits: append(android.Paths{apiFile, removedApiFile, d.apiFile, d.removedApiFile},
 			implicits...),
 		Args: map[string]string{
-			"srcJarDir":         android.PathForModuleOut(ctx, "srcjars").String(),
+			"srcJarDir":         android.PathForModuleOut(ctx, "apicheck-srcjars").String(),
 			"srcJars":           strings.Join(d.Javadoc.srcJars.Strings(), " "),
 			"javaVersion":       javaVersion,
 			"bootclasspathArgs": bootclasspathArgs,
diff --git a/java/java.go b/java/java.go
index 50c284a..5ed99f7 100644
--- a/java/java.go
+++ b/java/java.go
@@ -89,6 +89,9 @@
 	// list of module-specific flags that will be used for javac compiles
 	Javacflags []string `android:"arch_variant"`
 
+	// list of module-specific flags that will be used for kotlinc compiles
+	Kotlincflags []string `android:"arch_variant"`
+
 	// list of of java libraries that will be in the classpath
 	Libs []string `android:"arch_variant"`
 
@@ -330,6 +333,10 @@
 	return android.Paths{j.outputFile}
 }
 
+func (j *Module) DexJarFile() android.Path {
+	return j.dexJarFile
+}
+
 var _ android.SourceFileProducer = (*Module)(nil)
 
 type Dependency interface {
@@ -1083,13 +1090,21 @@
 	var kotlinJars android.Paths
 
 	if srcFiles.HasExt(".kt") {
+		// user defined kotlin flags.
+		kotlincFlags := j.properties.Kotlincflags
+		CheckKotlincFlags(ctx, kotlincFlags)
+
 		// If there are kotlin files, compile them first but pass all the kotlin and java files
 		// kotlinc will use the java files to resolve types referenced by the kotlin files, but
 		// won't emit any classes for them.
-
-		flags.kotlincFlags = "-no-stdlib"
+		kotlincFlags = append(kotlincFlags, "-no-stdlib")
 		if ctx.Device() {
-			flags.kotlincFlags += " -no-jdk"
+			kotlincFlags = append(kotlincFlags, "-no-jdk")
+		}
+		if len(kotlincFlags) > 0 {
+			// optimization.
+			ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " "))
+			flags.kotlincFlags += "$kotlincFlags"
 		}
 
 		var kotlinSrcFiles android.Paths
@@ -1328,6 +1343,31 @@
 	j.outputFile = outputFile.WithoutRel()
 }
 
+// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user,
+// since some of these flags may be used internally.
+func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
+	for _, flag := range flags {
+		flag = strings.TrimSpace(flag)
+
+		if !strings.HasPrefix(flag, "-") {
+			ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag)
+		} else if strings.HasPrefix(flag, "-Xintellij-plugin-root") {
+			ctx.PropertyErrorf("kotlincflags",
+				"Bad flag: `%s`, only use internal compiler for consistency.", flag)
+		} else if inList(flag, config.KotlincIllegalFlags) {
+			ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag)
+		} else if flag == "-include-runtime" {
+			ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag)
+		} else {
+			args := strings.Split(flag, " ")
+			if args[0] == "-kotlin-home" {
+				ctx.PropertyErrorf("kotlincflags",
+					"Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag)
+			}
+		}
+	}
+}
+
 func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
 	deps deps, flags javaBuilderFlags, jarName string, extraJars android.Paths) android.Path {
 
diff --git a/java/java_test.go b/java/java_test.go
index 86349fe..4d4b836 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1124,3 +1124,64 @@
 		}
 	}
 }
+
+var compilerFlagsTestCases = []struct {
+	in  string
+	out bool
+}{
+	{
+		in:  "a",
+		out: false,
+	},
+	{
+		in:  "-a",
+		out: true,
+	},
+	{
+		in:  "-no-jdk",
+		out: false,
+	},
+	{
+		in:  "-no-stdlib",
+		out: false,
+	},
+	{
+		in:  "-kotlin-home",
+		out: false,
+	},
+	{
+		in:  "-kotlin-home /some/path",
+		out: false,
+	},
+	{
+		in:  "-include-runtime",
+		out: false,
+	},
+	{
+		in:  "-Xintellij-plugin-root",
+		out: false,
+	},
+}
+
+type mockContext struct {
+	android.ModuleContext
+	result bool
+}
+
+func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
+	// CheckBadCompilerFlags calls this function when the flag should be rejected
+	ctx.result = false
+}
+
+func TestCompilerFlags(t *testing.T) {
+	for _, testCase := range compilerFlagsTestCases {
+		ctx := &mockContext{result: true}
+		CheckKotlincFlags(ctx, []string{testCase.in})
+		if ctx.result != testCase.out {
+			t.Errorf("incorrect output:")
+			t.Errorf("     input: %#v", testCase.in)
+			t.Errorf("  expected: %#v", testCase.out)
+			t.Errorf("       got: %#v", ctx.result)
+		}
+	}
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e513a59..573fc8e 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -229,19 +229,19 @@
 			// Create dist rules to install the stubs libs to the dist dir
 			if len(module.publicApiStubsPath) == 1 {
 				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.publicApiStubsPath.Strings()[0]+
+					module.publicApiStubsImplPath.Strings()[0]+
 					":"+path.Join("apistubs", owner, "public",
 					module.BaseModuleName()+".jar")+")")
 			}
 			if len(module.systemApiStubsPath) == 1 {
 				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.systemApiStubsPath.Strings()[0]+
+					module.systemApiStubsImplPath.Strings()[0]+
 					":"+path.Join("apistubs", owner, "system",
 					module.BaseModuleName()+".jar")+")")
 			}
 			if len(module.testApiStubsPath) == 1 {
 				fmt.Fprintln(w, "$(call dist-for-goals,sdk win_sdk,"+
-					module.testApiStubsPath.Strings()[0]+
+					module.testApiStubsImplPath.Strings()[0]+
 					":"+path.Join("apistubs", owner, "test",
 					module.BaseModuleName()+".jar")+")")
 			}
diff --git a/python/builder.go b/python/builder.go
index 11a792a..7ecd4b5 100644
--- a/python/builder.go
+++ b/python/builder.go
@@ -45,20 +45,22 @@
 	hostPar = pctx.AndroidStaticRule("hostPar",
 		blueprint.RuleParams{
 			Command: `sed -e 's/%interpreter%/$interp/g' -e 's/%main%/$main/g' $template > $stub && ` +
-				`$mergeParCmd -p -pm $stub $mergedZip $srcsZips && echo '#!/usr/bin/env python' | cat - $mergedZip > $out && ` +
-				`chmod +x $out && (rm -f $stub; rm -f $mergedZip)`,
+				`echo "#!/usr/bin/env python" >${out}.prefix &&` +
+				`$mergeParCmd -p --prefix ${out}.prefix -pm $stub $out $srcsZips && ` +
+				`chmod +x $out && (rm -f $stub; rm -f ${out}.prefix)`,
 			CommandDeps: []string{"$mergeParCmd"},
 		},
-		"interp", "main", "template", "stub", "mergedZip", "srcsZips")
+		"interp", "main", "template", "stub", "srcsZips")
 
 	embeddedPar = pctx.AndroidStaticRule("embeddedPar",
 		blueprint.RuleParams{
-			Command: `echo '$main' > $entryPoint &&` +
-				`$mergeParCmd -p -e $entryPoint $mergedZip $srcsZips && cat $launcher | cat - $mergedZip > $out && ` +
-				`chmod +x $out && (rm -f $entryPoint; rm -f $mergedZip)`,
+			// `echo -n` to trim the newline, since the python code just wants the name
+			Command: `echo -n '$main' > $entryPoint &&` +
+				`$mergeParCmd -p --prefix $launcher -e $entryPoint $out $srcsZips && ` +
+				`chmod +x $out && (rm -f $entryPoint)`,
 			CommandDeps: []string{"$mergeParCmd"},
 		},
-		"main", "entryPoint", "mergedZip", "srcsZips", "launcher")
+		"main", "entryPoint", "srcsZips", "launcher")
 )
 
 func init() {
@@ -73,9 +75,6 @@
 	launcherPath android.OptionalPath, interpreter, main, binName string,
 	srcsZips android.Paths) android.Path {
 
-	// .intermediate output path for merged zip file.
-	mergedZip := android.PathForModuleOut(ctx, binName+".mergedzip")
-
 	// .intermediate output path for bin executable.
 	binFile := android.PathForModuleOut(ctx, binName)
 
@@ -96,12 +95,11 @@
 			Output:      binFile,
 			Implicits:   implicits,
 			Args: map[string]string{
-				"interp":    strings.Replace(interpreter, "/", `\/`, -1),
-				"main":      strings.Replace(main, "/", `\/`, -1),
-				"template":  template.String(),
-				"stub":      stub,
-				"mergedZip": mergedZip.String(),
-				"srcsZips":  strings.Join(srcsZips.Strings(), " "),
+				"interp":   strings.Replace(interpreter, "/", `\/`, -1),
+				"main":     strings.Replace(main, "/", `\/`, -1),
+				"template": template.String(),
+				"stub":     stub,
+				"srcsZips": strings.Join(srcsZips.Strings(), " "),
 			},
 		})
 	} else if launcherPath.Valid() {
@@ -117,9 +115,8 @@
 			Output:      binFile,
 			Implicits:   implicits,
 			Args: map[string]string{
-				"main":       main,
+				"main":       strings.Replace(strings.TrimSuffix(main, pyExt), "/", ".", -1),
 				"entryPoint": entryPoint,
-				"mergedZip":  mergedZip.String(),
 				"srcsZips":   strings.Join(srcsZips.Strings(), " "),
 				"launcher":   launcherPath.String(),
 			},
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 81f8564..947458a 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -48,7 +48,8 @@
     "Malloc_not_svelte": false,
     "Safestack": false,
 
-    "Ndk_abis": true
+    "Ndk_abis": true,
+    "Exclude_draft_ndk_apis": true
 }
 EOF
 m --skip-make ${SOONG_OUT}/ndk.timestamp
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 07925df..64f49cb 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -61,7 +61,7 @@
                       help='specify additional <uses-library> tag to add. android:requred is set to false')
   parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
                       help='manifest is for a package built against the platform')
-  parser.add_argument('--prefer-integrity', type=bool, dest='prefer_integrity',
+  parser.add_argument('--prefer-integrity', dest='prefer_integrity', action='store_true',
                       help=('specify if the app prefers strict integrity. Should not be conflict if ' +
                             'already declared in the manifest.'))
   parser.add_argument('input', help='input AndroidManifest.xml file')
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index b4d76c4..db2e3bb 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -79,10 +79,8 @@
 	"bash":      Allowed,
 	"bc":        Allowed,
 	"bzip2":     Allowed,
-	"cat":       Allowed,
 	"chmod":     Allowed,
 	"cmp":       Allowed,
-	"comm":      Allowed,
 	"cp":        Allowed,
 	"cut":       Allowed,
 	"date":      Allowed,
@@ -92,7 +90,6 @@
 	"du":        Allowed,
 	"echo":      Allowed,
 	"egrep":     Allowed,
-	"env":       Allowed,
 	"expr":      Allowed,
 	"find":      Allowed,
 	"fuser":     Allowed,
@@ -104,7 +101,6 @@
 	"head":      Allowed,
 	"hexdump":   Allowed,
 	"hostname":  Allowed,
-	"id":        Allowed,
 	"jar":       Allowed,
 	"java":      Allowed,
 	"javap":     Allowed,
@@ -116,47 +112,36 @@
 	"mkdir":     Allowed,
 	"mktemp":    Allowed,
 	"mv":        Allowed,
-	"od":        Allowed,
 	"openssl":   Allowed,
-	"paste":     Allowed,
 	"patch":     Allowed,
 	"pgrep":     Allowed,
 	"pkill":     Allowed,
 	"ps":        Allowed,
 	"pstree":    Allowed,
-	"pwd":       Allowed,
 	"python":    Allowed,
 	"python2.7": Allowed,
 	"python3":   Allowed,
 	"readlink":  Allowed,
 	"realpath":  Allowed,
 	"rm":        Allowed,
-	"rmdir":     Allowed,
 	"rsync":     Allowed,
 	"sed":       Allowed,
-	"setsid":    Allowed,
 	"sh":        Allowed,
 	"sha1sum":   Allowed,
 	"sha256sum": Allowed,
 	"sha512sum": Allowed,
-	"sleep":     Allowed,
 	"sort":      Allowed,
 	"stat":      Allowed,
 	"tar":       Allowed,
-	"tail":      Allowed,
-	"tee":       Allowed,
 	"timeout":   Allowed,
 	"todos":     Allowed,
 	"touch":     Allowed,
 	"tr":        Allowed,
-	"uniq":      Allowed,
 	"unix2dos":  Allowed,
 	"unzip":     Allowed,
 	"wc":        Allowed,
 	"which":     Allowed,
-	"whoami":    Allowed,
 	"xargs":     Allowed,
-	"xxd":       Allowed,
 	"xz":        Allowed,
 	"zip":       Allowed,
 	"zipinfo":   Allowed,
@@ -176,8 +161,23 @@
 	"pkg-config": Forbidden,
 
 	// On linux we'll use the toybox version of these instead
-	"true":  Toybox,
-	"uname": Toybox,
+	"cat":    Toybox,
+	"comm":   Toybox,
+	"env":    Toybox,
+	"id":     Toybox,
+	"od":     Toybox,
+	"paste":  Toybox,
+	"pwd":    Toybox,
+	"rmdir":  Toybox,
+	"setsid": Toybox,
+	"sleep":  Toybox,
+	"tail":   Toybox,
+	"tee":    Toybox,
+	"true":   Toybox,
+	"uname":  Toybox,
+	"uniq":   Toybox,
+	"whoami": Toybox,
+	"xxd":    Toybox,
 }
 
 func init() {