Merge "Add to support armv8-2a on 2nd arch. variant"
diff --git a/android/arch.go b/android/arch.go
index 2543fca..7fe1b18 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)
+				}
 			}
 		}
 	}
diff --git a/android/config.go b/android/config.go
index cca1c7a..695a298 100644
--- a/android/config.go
+++ b/android/config.go
@@ -351,10 +351,6 @@
 
 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 {
diff --git a/android/module.go b/android/module.go
index 556c73d..bf49ca2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -280,7 +280,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,7 +435,7 @@
 	variableProperties      variableProperties
 	hostAndDeviceProperties hostAndDeviceProperties
 	generalProperties       []interface{}
-	archProperties          []interface{}
+	archProperties          [][]interface{}
 	customizableProperties  []interface{}
 
 	noAddressSanitizer bool
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/apex/apex.go b/apex/apex.go
index 6819bff..3e7c0a7 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -445,6 +445,11 @@
 		return false
 	})
 
+	if keyFile == nil {
+		ctx.PropertyErrorf("key", "private_key for %q could not be found", String(a.properties.Key))
+		return
+	}
+
 	cert := String(a.properties.Certificate)
 	if cert != "" && android.SrcIsModule(cert) == "" {
 		defaultDir := ctx.Config().DefaultAppCertificateDir(ctx)
diff --git a/cc/builder.go b/cc/builder.go
index 3d12538..6d5b595 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -247,7 +247,6 @@
 	systemIncludeFlags string
 
 	groupStaticLibs bool
-	arGoldPlugin    bool
 
 	stripKeepSymbols       bool
 	stripKeepMiniDebugInfo bool
@@ -485,9 +484,6 @@
 	if !ctx.Darwin() {
 		arFlags += " -format=gnu"
 	}
-	if flags.arGoldPlugin {
-		arFlags += " --plugin ${config.LLVMGoldPlugin}"
-	}
 	if flags.arFlags != "" {
 		arFlags += " " + flags.arFlags
 	}
diff --git a/cc/cc.go b/cc/cc.go
index 0569563..9a44bde 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -157,7 +157,6 @@
 	LdFlagsDeps android.Paths // Files depended on by linker flags
 
 	GroupStaticLibs bool
-	ArGoldPlugin    bool // Whether LLVM gold plugin option is passed to llvm-ar
 }
 
 type ObjectLinkerProperties struct {
@@ -1611,7 +1610,6 @@
 		&VendorProperties{},
 		&BaseCompilerProperties{},
 		&BaseLinkerProperties{},
-		&MoreBaseLinkerProperties{},
 		&LibraryProperties{},
 		&FlagExporterProperties{},
 		&BinaryLinkerProperties{},
diff --git a/cc/cc_test.go b/cc/cc_test.go
index e4904f2..d6ffe51 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -894,9 +894,7 @@
 		}
 	`)
 
-	// The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
-	// but target.vendor.shared_libs has not been supported yet.
-	testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
+	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
 		cc_library {
 			name: "libvndk",
 			vendor_available: true,
@@ -965,9 +963,7 @@
 		}
 	`)
 
-	// The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
-	// but target.vendor.shared_libs has not been supported yet.
-	testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
+	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
 		cc_library {
 			name: "libvndk_sp",
 			vendor_available: true,
diff --git a/cc/compdb.go b/cc/compdb.go
index acfc924..4dfc55b 100644
--- a/cc/compdb.go
+++ b/cc/compdb.go
@@ -126,28 +126,32 @@
 	return out
 }
 
-func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Module) []string {
+func getArguments(src android.Path, ctx android.SingletonContext, ccModule *Module, ccPath string, cxxPath string) []string {
 	var args []string
 	isCpp := false
 	isAsm := false
 	// TODO It would be better to ask soong for the types here.
+	var clangPath string
 	switch src.Ext() {
 	case ".S", ".s", ".asm":
 		isAsm = true
 		isCpp = false
+		clangPath = ccPath
 	case ".c":
 		isAsm = false
 		isCpp = false
+		clangPath = ccPath
 	case ".cpp", ".cc", ".mm":
 		isAsm = false
 		isCpp = true
+		clangPath = cxxPath
 	default:
 		log.Print("Unknown file extension " + src.Ext() + " on file " + src.String())
 		isAsm = true
 		isCpp = false
+		clangPath = ccPath
 	}
-	// The executable for the compilation doesn't matter but we need something there.
-	args = append(args, "/bin/false")
+	args = append(args, clangPath)
 	args = append(args, expandAllVars(ctx, ccModule.flags.GlobalFlags)...)
 	args = append(args, expandAllVars(ctx, ccModule.flags.CFlags)...)
 	if isCpp {
@@ -166,12 +170,19 @@
 		return
 	}
 
+	pathToCC, err := ctx.Eval(pctx, "${config.ClangBin}/")
+	ccPath := "/bin/false"
+	cxxPath := "/bin/false"
+	if err == nil {
+		ccPath = pathToCC + "clang"
+		cxxPath = pathToCC + "clang++"
+	}
 	rootDir := getCompdbAndroidSrcRootDirectory(ctx)
 	for _, src := range srcs {
 		if _, ok := builds[src.String()]; !ok {
 			builds[src.String()] = compDbEntry{
 				Directory: rootDir,
-				Arguments: getArguments(src, ctx, ccModule),
+				Arguments: getArguments(src, ctx, ccModule, ccPath, cxxPath),
 				File:      src.String(),
 			}
 		}
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index bcff775..6a63828 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -25,11 +25,6 @@
 	arm64Cflags = []string{
 		// Help catch common 32/64-bit errors.
 		"-Werror=implicit-function-declaration",
-
-		// Prevent use of x18 register.
-		// TODO(pcc): Remove this flag once we upgrade past LLVM r340889
-		// which does this by default on Android.
-		"-ffixed-x18",
 	}
 
 	arm64ArchVariantCflags = map[string][]string{
diff --git a/cc/config/clang.go b/cc/config/clang.go
index 74e8ae8..0f22034 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -129,6 +129,9 @@
 		// Warnings from clang-7.0
 		"-Wno-deprecated-register",
 		"-Wno-sign-compare",
+
+		// Warnings from clang-8.0
+		"-Wno-defaulted-function-deleted",
 	}, " "))
 
 	pctx.StaticVariable("ClangExtraCppflags", strings.Join([]string{
diff --git a/cc/config/global.go b/cc/config/global.go
index 3e76373..e2377e3 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -15,7 +15,6 @@
 package config
 
 import (
-	"runtime"
 	"strings"
 
 	"android/soong/android"
@@ -88,9 +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",
@@ -126,8 +122,8 @@
 
 	// prebuilts/clang default settings.
 	ClangDefaultBase         = "prebuilts/clang/host"
-	ClangDefaultVersion      = "clang-r339409b"
-	ClangDefaultShortVersion = "8.0.2"
+	ClangDefaultVersion      = "clang-r344140b"
+	ClangDefaultShortVersion = "8.0.4"
 
 	// Directories with warnings from Android.bp files.
 	WarningAllowedProjects = []string{
@@ -211,11 +207,6 @@
 		return ClangDefaultShortVersion
 	})
 	pctx.StaticVariable("ClangAsanLibDir", "${ClangBase}/linux-x86/${ClangVersion}/lib64/clang/${ClangShortVersion}/lib/linux")
-	if runtime.GOOS == "darwin" {
-		pctx.StaticVariable("LLVMGoldPlugin", "${ClangPath}/lib64/LLVMgold.dylib")
-	} else {
-		pctx.StaticVariable("LLVMGoldPlugin", "${ClangPath}/lib64/LLVMgold.so")
-	}
 
 	// These are tied to the version of LLVM directly in external/llvm, so they might trail the host prebuilts
 	// being used for the rest of the build process.
diff --git a/cc/linker.go b/cc/linker.go
index e96bfcb..3053609 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -99,6 +99,10 @@
 
 	Target struct {
 		Vendor struct {
+			// list of shared libs that only should be used to build the vendor
+			// variant of the C/C++ module.
+			Shared_libs []string
+
 			// list of shared libs that should not be used to build the vendor variant
 			// of the C/C++ module.
 			Exclude_shared_libs []string
@@ -114,8 +118,15 @@
 			// 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
+			// variant of the C/C++ module.
+			Shared_libs []string
+
 			// list of shared libs that should not be used to build
 			// the recovery variant of the C/C++ module.
 			Exclude_shared_libs []string
@@ -132,23 +143,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 {
@@ -158,7 +158,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"`
@@ -180,7 +179,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 {
@@ -200,6 +199,7 @@
 	}
 
 	if ctx.useVndk() {
+		deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Vendor.Shared_libs...)
 		deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor.Exclude_shared_libs)
 		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor.Exclude_shared_libs)
 		deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Vendor.Exclude_static_libs)
@@ -210,6 +210,7 @@
 	}
 
 	if ctx.inRecovery() {
+		deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Recovery.Shared_libs...)
 		deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs)
 		deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Recovery.Exclude_shared_libs)
 		deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Recovery.Exclude_static_libs)
@@ -273,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
@@ -309,7 +310,7 @@
 
 	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 {
@@ -384,11 +385,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/lto.go b/cc/lto.go
index d9d2662..6302748 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -105,21 +105,12 @@
 			flags.LdFlags = append(flags.LdFlags, cachePolicyFormat+policy)
 		}
 
-		flags.ArGoldPlugin = true
-
 		// If the module does not have a profile, be conservative and do not inline
 		// or unroll loops during LTO, in order to prevent significant size bloat.
 		if !ctx.isPgoCompile() && !lto.useClangLld(ctx) {
 			flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-inline-threshold=0")
 			flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-unroll-threshold=0")
 		}
-
-		if ctx.Arch().ArchType == android.Arm64 {
-			// Prevent use of x18 register on arm64.
-			// TODO(pcc): Remove this flag once we upgrade past LLVM r340889
-			// which does this by default on Android.
-			flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
-		}
 	}
 	return flags
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 527ae33..cd3b3e9 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -466,18 +466,10 @@
 			flags.CFlags = append(flags.CFlags, "-fvisibility=default")
 		}
 		flags.LdFlags = append(flags.LdFlags, cfiLdflags...)
-		flags.ArGoldPlugin = true
 		if Bool(sanitize.Properties.Sanitize.Diag.Cfi) {
 			diagSanitizers = append(diagSanitizers, "cfi")
 		}
 
-		if ctx.Arch().ArchType == android.Arm64 {
-			// Prevent use of x18 register on arm64.
-			// TODO(pcc): Remove this flag once we upgrade past LLVM r340889
-			// which does this by default on Android.
-			flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
-		}
-
 		if ctx.staticBinary() {
 			_, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags)
 			_, flags.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.LdFlags)
diff --git a/cc/util.go b/cc/util.go
index 1412d54..c900423 100644
--- a/cc/util.go
+++ b/cc/util.go
@@ -86,7 +86,6 @@
 		systemIncludeFlags: strings.Join(in.SystemIncludeFlags, " "),
 
 		groupStaticLibs: in.GroupStaticLibs,
-		arGoldPlugin:    in.ArGoldPlugin,
 	}
 }
 
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/java/builder.go b/java/builder.go
index c52e942..cefb916 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -161,7 +161,6 @@
 	kotlincClasspath classpath
 
 	protoFlags       []string
-	protoDeps        android.Paths
 	protoOutTypeFlag string // The flag itself: --java_out
 	protoOutParams   string // Parameters to that flag: --java_out=$protoOutParams:$outDir
 	protoRoot        bool
diff --git a/java/proto.go b/java/proto.go
index 0bb37c5..8028039 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -59,7 +59,6 @@
 		Description: "protoc " + protoFile.Rel(),
 		Output:      srcJarFile,
 		Input:       protoFile,
-		Implicits:   flags.protoDeps,
 		Args: map[string]string{
 			"protoBase":      protoBase,
 			"protoOut":       flags.protoOutTypeFlag,
@@ -94,16 +93,14 @@
 func protoFlags(ctx android.ModuleContext, j *CompilerProperties, p *android.ProtoProperties,
 	flags javaBuilderFlags) javaBuilderFlags {
 
-	var plugin string
-
 	switch String(p.Proto.Type) {
 	case "micro":
 		flags.protoOutTypeFlag = "--javamicro_out"
 	case "nano":
 		flags.protoOutTypeFlag = "--javanano_out"
 	case "lite":
-		plugin = "protoc-gen-javalite"
-		flags.protoOutTypeFlag = "--javalite_out"
+		flags.protoOutTypeFlag = "--java_out"
+		flags.protoOutParams = "lite"
 	case "full", "":
 		flags.protoOutTypeFlag = "--java_out"
 	default:
@@ -111,15 +108,15 @@
 			String(p.Proto.Type))
 	}
 
-	flags.protoOutParams = strings.Join(j.Proto.Output_params, ",")
+	if len(j.Proto.Output_params) > 0 {
+		if flags.protoOutParams != "" {
+			flags.protoOutParams += ","
+		}
+		flags.protoOutParams += strings.Join(j.Proto.Output_params, ",")
+	}
+
 	flags.protoFlags = android.ProtoFlags(ctx, p)
 	flags.protoRoot = android.ProtoCanonicalPathFromRoot(ctx, p)
 
-	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/ui/build/paths/config.go b/ui/build/paths/config.go
index b4d76c4..f3406e5 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -104,7 +104,6 @@
 	"head":      Allowed,
 	"hexdump":   Allowed,
 	"hostname":  Allowed,
-	"id":        Allowed,
 	"jar":       Allowed,
 	"java":      Allowed,
 	"javap":     Allowed,
@@ -154,7 +153,6 @@
 	"unzip":     Allowed,
 	"wc":        Allowed,
 	"which":     Allowed,
-	"whoami":    Allowed,
 	"xargs":     Allowed,
 	"xxd":       Allowed,
 	"xz":        Allowed,
@@ -176,8 +174,10 @@
 	"pkg-config": Forbidden,
 
 	// On linux we'll use the toybox version of these instead
-	"true":  Toybox,
-	"uname": Toybox,
+	"id":     Toybox,
+	"true":   Toybox,
+	"uname":  Toybox,
+	"whoami": Toybox,
 }
 
 func init() {