Merge "Support tagged module references"
diff --git a/android/arch.go b/android/arch.go
index 68fc149..04eb1e2 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -710,7 +710,7 @@
 //    - The HostOrDeviceSupported value passed in to InitAndroidArchModule by the module type factory, which selects
 //      whether the module type can compile for host, device or both.
 //    - The host_supported and device_supported properties on the module.
-// If host is supported for the module, the Host and HostCross OsClasses are  are selected.  If device is supported
+// If host is supported for the module, the Host and HostCross OsClasses are selected.  If device is supported
 // for the module, the Device OsClass is selected.
 // Within each selected OsClass, the multilib selection is determined by:
 //    - The compile_multilib property if it set (which may be overriden by target.android.compile_multlib or
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
index b13ce2a..069e1f5 100644
--- a/android/prebuilt_etc.go
+++ b/android/prebuilt_etc.go
@@ -24,6 +24,7 @@
 	RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory)
 	RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory)
 	RegisterModuleType("prebuilt_font", PrebuiltFontFactory)
+	RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory)
 
 	PreDepsMutators(func(ctx RegisterMutatorsContext) {
 		ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
@@ -61,7 +62,9 @@
 	sourceFilePath Path
 	outputFilePath OutputPath
 	// The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share.
-	installDirBase         string
+	installDirBase string
+	// The base install location when soc_specific property is set to true, e.g. "firmware" for prebuilt_firmware.
+	socInstallDirBase      string
 	installDirPath         OutputPath
 	additionalDependencies *Paths
 }
@@ -121,7 +124,14 @@
 		return
 	}
 	p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
-	p.installDirPath = PathForModuleInstall(ctx, p.installDirBase, String(p.properties.Sub_dir))
+
+	// If soc install dir was specified and SOC specific is set, set the installDirPath to the specified
+	// socInstallDirBase.
+	installBaseDir := p.installDirBase
+	if ctx.SocSpecific() && p.socInstallDirBase != "" {
+		installBaseDir = p.socInstallDirBase
+	}
+	p.installDirPath = PathForModuleInstall(ctx, installBaseDir, String(p.properties.Sub_dir))
 
 	// This ensures that outputFilePath has the correct name for others to
 	// use, as the source file may have a different name.
@@ -250,3 +260,14 @@
 	InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
 	return module
 }
+
+// prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system image.
+// If soc_specific property is set to true, the firmware file is installed to the vendor <partition>/firmware
+// directory for vendor image.
+func PrebuiltFirmwareFactory() Module {
+	module := &PrebuiltEtc{installDirBase: "etc/firmware", socInstallDirBase: "firmware"}
+	InitPrebuiltEtcModule(module)
+	// This module is device-only
+	InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
+	return module
+}
diff --git a/android/prebuilt_etc_test.go b/android/prebuilt_etc_test.go
index a5c4480..d977c30 100644
--- a/android/prebuilt_etc_test.go
+++ b/android/prebuilt_etc_test.go
@@ -31,6 +31,7 @@
 	ctx.RegisterModuleType("prebuilt_usr_share", ModuleFactoryAdaptor(PrebuiltUserShareFactory))
 	ctx.RegisterModuleType("prebuilt_usr_share_host", ModuleFactoryAdaptor(PrebuiltUserShareHostFactory))
 	ctx.RegisterModuleType("prebuilt_font", ModuleFactoryAdaptor(PrebuiltFontFactory))
+	ctx.RegisterModuleType("prebuilt_firmware", ModuleFactoryAdaptor(PrebuiltFirmwareFactory))
 	ctx.PreDepsMutators(func(ctx RegisterMutatorsContext) {
 		ctx.BottomUp("prebuilt_etc", prebuiltEtcMutator).Parallel()
 	})
@@ -235,3 +236,39 @@
 		t.Errorf("expected %q, got %q", expected, p.installDirPath.RelPathString())
 	}
 }
+
+func TestPrebuiltFirmwareDirPath(t *testing.T) {
+	targetPath := "target/product/test_device"
+	tests := []struct {
+		description  string
+		config       string
+		expectedPath string
+	}{{
+		description: "prebuilt: system firmware",
+		config: `
+			prebuilt_firmware {
+				name: "foo.conf",
+				src: "foo.conf",
+			}`,
+		expectedPath: filepath.Join(targetPath, "system/etc/firmware"),
+	}, {
+		description: "prebuilt: vendor firmware",
+		config: `
+			prebuilt_firmware {
+				name: "foo.conf",
+				src: "foo.conf",
+				soc_specific: true,
+				sub_dir: "sub_dir",
+			}`,
+		expectedPath: filepath.Join(targetPath, "vendor/firmware/sub_dir"),
+	}}
+	for _, tt := range tests {
+		t.Run(tt.description, func(t *testing.T) {
+			ctx, _ := testPrebuiltEtc(t, tt.config)
+			p := ctx.ModuleForTests("foo.conf", "android_arm64_armv8-a_core").Module().(*PrebuiltEtc)
+			if p.installDirPath.RelPathString() != tt.expectedPath {
+				t.Errorf("expected %q, got %q", tt.expectedPath, p.installDirPath)
+			}
+		})
+	}
+}
diff --git a/androidmk/cmd/androidmk/androidmk_test.go b/androidmk/cmd/androidmk/androidmk_test.go
index 2eab0cc..4d5180e 100644
--- a/androidmk/cmd/androidmk/androidmk_test.go
+++ b/androidmk/cmd/androidmk/androidmk_test.go
@@ -1179,6 +1179,84 @@
 `,
 	},
 	{
+		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_ETC)",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_firmware {
+	name: "foo",
+
+	src: "foo.fw",
+	sub_dir: "bar",
+}
+`,
+	},
+	{
+		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_firmware {
+	name: "foo",
+
+	src: "foo.fw",
+	sub_dir: "bar",
+}
+`,
+	},
+	{
+		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT_VENDOR)",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR)/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_firmware {
+	name: "foo",
+
+	src: "foo.fw",
+	sub_dir: "bar",
+	proprietary: true,
+}
+`,
+	},
+	{
+		desc: "prebuilt_firmware subdir_bar in $(TARGET_OUT)/vendor",
+		in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/vendor/firmware/bar
+LOCAL_SRC_FILES := foo.fw
+include $(BUILD_PREBUILT)
+`,
+		expected: `
+prebuilt_firmware {
+	name: "foo",
+
+	src: "foo.fw",
+	sub_dir: "bar",
+	proprietary: true,
+}
+`,
+	},
+	{
 		desc: "vts_config",
 		in: `
 include $(CLEAR_VARS)
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 5276ce4..f71abd7 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -585,7 +585,7 @@
 
 		cc_library {
 			name: "libc",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
@@ -596,7 +596,7 @@
 
 		cc_library {
 			name: "libm",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
@@ -607,7 +607,7 @@
 
 		cc_library {
 			name: "libdl",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 17cff18..cac4d9a 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -503,16 +503,18 @@
 }
 
 var localModuleUpdate = map[string][]etcPrebuiltModuleUpdate{
-	"HOST_OUT":                        {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
-	"PRODUCT_OUT":                     {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
-	"TARGET_OUT":                      {{prefix: "/etc"}, {prefix: "/usr/share", modType: "prebuilt_usr_share"}, {prefix: "/fonts", modType: "prebuilt_font"}},
-	"TARGET_OUT_ETC":                  {{prefix: ""}},
+	"HOST_OUT":    {{prefix: "/etc", modType: "prebuilt_etc_host"}, {prefix: "/usr/share", modType: "prebuilt_usr_share_host"}},
+	"PRODUCT_OUT": {{prefix: "/system/etc"}, {prefix: "/vendor/etc", flags: []string{"proprietary"}}},
+	"TARGET_OUT": {{prefix: "/usr/share", modType: "prebuilt_usr_share"}, {prefix: "/fonts", modType: "prebuilt_font"},
+		{prefix: "/etc/firmware", modType: "prebuilt_firmware"}, {prefix: "/vendor/firmware", modType: "prebuilt_firmware", flags: []string{"proprietary"}},
+		{prefix: "/etc"}},
+	"TARGET_OUT_ETC":                  {{prefix: "/firmware", modType: "prebuilt_firmware"}, {prefix: ""}},
 	"TARGET_OUT_PRODUCT":              {{prefix: "/etc", flags: []string{"product_specific"}}, {prefix: "/fonts", modType: "prebuilt_font", flags: []string{"product_specific"}}},
 	"TARGET_OUT_PRODUCT_ETC":          {{prefix: "", flags: []string{"product_specific"}}},
 	"TARGET_OUT_ODM":                  {{prefix: "/etc", flags: []string{"device_specific"}}},
 	"TARGET_OUT_PRODUCT_SERVICES":     {{prefix: "/etc", flags: []string{"product_services_specific"}}},
 	"TARGET_OUT_PRODUCT_SERVICES_ETC": {{prefix: "", flags: []string{"product_services_specific"}}},
-	"TARGET_OUT_VENDOR":               {{prefix: "/etc", flags: []string{"proprietary"}}},
+	"TARGET_OUT_VENDOR":               {{prefix: "/etc", flags: []string{"proprietary"}}, {prefix: "/firmware", modType: "prebuilt_firmware", flags: []string{"proprietary"}}},
 	"TARGET_OUT_VENDOR_ETC":           {{prefix: "", flags: []string{"proprietary"}}},
 	"TARGET_RECOVERY_ROOT_OUT":        {{prefix: "/system/etc", flags: []string{"recovery"}}},
 }
diff --git a/cc/binary.go b/cc/binary.go
index 93d1de2..8428d7e 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -326,7 +326,7 @@
 		}
 		strippedOutputFile := outputFile
 		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
-		binary.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
+		binary.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
 	}
 
 	binary.unstrippedOutputFile = outputFile
@@ -350,7 +350,7 @@
 			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.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
 			}
 
 			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 997e11e..ca34185 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -184,7 +184,7 @@
 		cc_library {
 			name: "libTest",
 			srcs: ["foo.c"],
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			vendor_available: true,
@@ -647,7 +647,7 @@
 	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
 		cc_library {
 			name: "libllndk",
-			no_libgcc: true,
+			no_libcrt: true,
 			shared_libs: ["libnondoubleloadable"],
 		}
 
@@ -1786,7 +1786,7 @@
 		shared_libs: ["libllndk"],
 		vendor: true,
 		srcs: ["foo.c"],
-		no_libgcc: true,
+		no_libcrt: true,
 		nocrt: true,
 	}
 	`)
@@ -1815,7 +1815,7 @@
 	cc_library {
 		name: "libvendor_available1",
 		vendor_available: true,
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
@@ -1823,7 +1823,7 @@
 		name: "libvendor_available2",
 		vendor_available: true,
 		runtime_libs: ["libvendor_available1"],
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
@@ -1836,21 +1836,21 @@
 				exclude_runtime_libs: ["libvendor_available1"],
 			}
 		},
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
 	cc_library {
 		name: "libcore",
 		runtime_libs: ["libvendor_available1"],
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
 	cc_library {
 		name: "libvendor1",
 		vendor: true,
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
@@ -1858,7 +1858,7 @@
 		name: "libvendor2",
 		vendor: true,
 		runtime_libs: ["libvendor_available1", "libvendor1"],
-		no_libgcc : true,
+		no_libcrt : true,
 		nocrt : true,
 		system_shared_libs : [],
 	}
@@ -2050,7 +2050,7 @@
 		name: "libvendorpublic",
 		srcs: ["foo.c"],
 		vendor: true,
-		no_libgcc: true,
+		no_libcrt: true,
 		nocrt: true,
 	}
 
@@ -2059,7 +2059,7 @@
 		shared_libs: ["libvendorpublic"],
 		vendor: false,
 		srcs: ["foo.c"],
-		no_libgcc: true,
+		no_libcrt: true,
 		nocrt: true,
 	}
 	cc_library {
@@ -2067,7 +2067,7 @@
 		shared_libs: ["libvendorpublic"],
 		vendor: true,
 		srcs: ["foo.c"],
-		no_libgcc: true,
+		no_libcrt: true,
 		nocrt: true,
 	}
 	`)
diff --git a/cc/library.go b/cc/library.go
index 3053831..0bc5b5b 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -721,7 +721,7 @@
 		}
 		strippedOutputFile := outputFile
 		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
-		library.stripper.strip(ctx, outputFile, strippedOutputFile, builderFlags)
+		library.stripper.stripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, builderFlags)
 	}
 
 	library.unstrippedOutputFile = outputFile
@@ -738,7 +738,7 @@
 			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.stripper.stripExecutableOrSharedLib(ctx, versionedOutputFile, out, builderFlags)
 			}
 
 			library.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
diff --git a/cc/linker.go b/cc/linker.go
index 986a562..dda2fcb 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -57,9 +57,6 @@
 	// This flag should only be necessary for compiling low-level libraries like libc.
 	Allow_undefined_symbols *bool `android:"arch_variant"`
 
-	// don't link in libgcc.a
-	No_libgcc *bool
-
 	// don't link in libclang_rt.builtins-*.a
 	No_libcrt *bool `android:"arch_variant"`
 
@@ -230,9 +227,6 @@
 			deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
 			deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
 			deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped")
-		} else if !Bool(linker.Properties.No_libgcc) {
-			deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
-			deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
 		}
 
 		systemSharedLibs := linker.Properties.System_shared_libs
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 48e4667..f92c50d 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -98,7 +98,7 @@
 			libName := ctx.baseModuleName() + flags.Toolchain.ShlibSuffix()
 			if p.needsStrip(ctx) {
 				stripped := android.PathForModuleOut(ctx, "stripped", libName)
-				p.strip(ctx, in, stripped, builderFlags)
+				p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
 				in = stripped
 			}
 
@@ -197,7 +197,7 @@
 
 		if p.needsStrip(ctx) {
 			stripped := android.PathForModuleOut(ctx, "stripped", fileName)
-			p.strip(ctx, in, stripped, builderFlags)
+			p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
 			in = stripped
 		}
 
diff --git a/cc/strip.go b/cc/strip.go
index 4daa759..f3e3374 100644
--- a/cc/strip.go
+++ b/cc/strip.go
@@ -41,7 +41,7 @@
 }
 
 func (stripper *stripper) strip(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
-	flags builderFlags) {
+	flags builderFlags, isStaticLib bool) {
 	if ctx.Darwin() {
 		TransformDarwinStrip(ctx, in, out)
 	} else {
@@ -57,9 +57,19 @@
 		if Bool(stripper.StripProperties.Strip.Use_gnu_strip) {
 			flags.stripUseGnuStrip = true
 		}
-		if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo {
+		if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo && !isStaticLib {
 			flags.stripAddGnuDebuglink = true
 		}
 		TransformStrip(ctx, in, out, flags)
 	}
 }
+
+func (stripper *stripper) stripExecutableOrSharedLib(ctx ModuleContext, in android.Path,
+	out android.ModuleOutPath, flags builderFlags) {
+	stripper.strip(ctx, in, out, flags, false)
+}
+
+func (stripper *stripper) stripStaticLib(ctx ModuleContext, in android.Path, out android.ModuleOutPath,
+	flags builderFlags) {
+	stripper.strip(ctx, in, out, flags, true)
+}
diff --git a/cc/testing.go b/cc/testing.go
index d9be900..df7cb78 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -78,7 +78,7 @@
 
 		cc_library {
 			name: "libc",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			recovery_available: true,
@@ -89,7 +89,7 @@
 		}
 		cc_library {
 			name: "libm",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			recovery_available: true,
@@ -100,7 +100,7 @@
 		}
 		cc_library {
 			name: "libdl",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			recovery_available: true,
@@ -111,7 +111,7 @@
 		}
 		cc_library {
 			name: "libc++_static",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
@@ -120,7 +120,7 @@
 		}
 		cc_library {
 			name: "libc++",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
@@ -133,7 +133,7 @@
 		}
 		cc_library {
 			name: "libunwind_llvm",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			stl: "none",
diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go
index b4c51ab..fef4508 100644
--- a/cc/toolchain_library.go
+++ b/cc/toolchain_library.go
@@ -86,7 +86,7 @@
 		fileName := ctx.ModuleName() + staticLibraryExtension
 		outputFile := android.PathForModuleOut(ctx, fileName)
 		buildFlags := flagsToBuilderFlags(flags)
-		library.stripper.strip(ctx, srcPath, outputFile, buildFlags)
+		library.stripper.stripStaticLib(ctx, srcPath, outputFile, buildFlags)
 		return outputFile
 	}
 
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index d78238a..b470ba5 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -278,7 +278,7 @@
 
 		cc_library {
 			name: "liblog",
-			no_libgcc: true,
+			no_libcrt: true,
 			nocrt: true,
 			system_shared_libs: [],
 			recovery_available: true,