Migrate Rust to LLVM coverage.

Bug: 177675913
Test: Manually compile, run, and see output with llvm-cov.
Change-Id: I66729cff87a848782e9fa1b95cbbc06318c5761a
diff --git a/rust/androidmk.go b/rust/androidmk.go
index e9da6fa..0307727 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -82,9 +82,6 @@
 	}
 
 	ret.Class = "EXECUTABLES"
-	ret.ExtraEntries = append(ret.ExtraEntries, func(entries *android.AndroidMkEntries) {
-		entries.SetOptionalPath("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputZipFile)
-	})
 }
 
 func (test *testDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
@@ -117,10 +114,6 @@
 	if library.distFile.Valid() {
 		ret.DistFiles = android.MakeDefaultDistFiles(library.distFile.Path())
 	}
-
-	ret.ExtraEntries = append(ret.ExtraEntries, func(entries *android.AndroidMkEntries) {
-		entries.SetOptionalPath("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputZipFile)
-	})
 }
 
 func (procMacro *procMacroDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkEntries) {
diff --git a/rust/binary.go b/rust/binary.go
index ca07d07..2963a37 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -121,7 +121,7 @@
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 	flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
 
-	outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+	TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 
 	if binary.stripper.NeedsStrip(ctx) {
 		strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
@@ -129,24 +129,9 @@
 		binary.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
 	}
 
-	binary.coverageFile = outputs.coverageFile
-
-	var coverageFiles android.Paths
-	if outputs.coverageFile != nil {
-		coverageFiles = append(coverageFiles, binary.coverageFile)
-	}
-	if len(deps.coverageFiles) > 0 {
-		coverageFiles = append(coverageFiles, deps.coverageFiles...)
-	}
-	binary.coverageOutputZipFile = TransformCoverageFilesToZip(ctx, coverageFiles, binary.getStem(ctx))
-
 	return outputFile
 }
 
-func (binary *binaryDecorator) coverageOutputZipPath() android.OptionalPath {
-	return binary.coverageOutputZipFile
-}
-
 func (binary *binaryDecorator) autoDep(ctx BaseModuleContext) autoDep {
 	// Binaries default to dylib dependencies for device, rlib for host.
 	if binary.preferRlib() {
diff --git a/rust/builder.go b/rust/builder.go
index e5f0ab5..becebfe 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -19,10 +19,8 @@
 	"strings"
 
 	"github.com/google/blueprint"
-	"github.com/google/blueprint/pathtools"
 
 	"android/soong/android"
-	"android/soong/cc"
 	"android/soong/rust/config"
 )
 
@@ -76,8 +74,7 @@
 )
 
 type buildOutput struct {
-	outputFile   android.Path
-	coverageFile android.Path
+	outputFile android.Path
 }
 
 func init() {
@@ -195,27 +192,6 @@
 		implicits = append(implicits, deps.CrtBegin.Path(), deps.CrtEnd.Path())
 	}
 
-	if flags.Coverage {
-		var gcnoFile android.WritablePath
-		// Provide consistency with cc gcda output, see cc/builder.go init()
-		profileEmitArg := strings.TrimPrefix(cc.PwdPrefix(), "PWD=") + "/"
-
-		if outputFile.Ext() != "" {
-			// rustc seems to split the output filename at the first '.' when determining the gcno filename
-			// so we need to do the same here.
-			gcnoFile = android.PathForModuleOut(ctx, strings.Split(outputFile.Base(), ".")[0]+".gcno")
-			rustcFlags = append(rustcFlags, "-Z profile-emit="+profileEmitArg+android.PathForModuleOut(
-				ctx, pathtools.ReplaceExtension(outputFile.Base(), "gcda")).String())
-		} else {
-			gcnoFile = android.PathForModuleOut(ctx, outputFile.Base()+".gcno")
-			rustcFlags = append(rustcFlags, "-Z profile-emit="+profileEmitArg+android.PathForModuleOut(
-				ctx, outputFile.Base()+".gcda").String())
-		}
-
-		implicitOutputs = append(implicitOutputs, gcnoFile)
-		output.coverageFile = gcnoFile
-	}
-
 	if len(deps.SrcDeps) > 0 {
 		genSubDir := "out/"
 		moduleGenDir := android.PathForModuleOut(ctx, genSubDir)
@@ -292,21 +268,3 @@
 
 	return output
 }
-
-func TransformCoverageFilesToZip(ctx ModuleContext,
-	covFiles android.Paths, baseName string) android.OptionalPath {
-	if len(covFiles) > 0 {
-
-		outputFile := android.PathForModuleOut(ctx, baseName+".zip")
-
-		ctx.Build(pctx, android.BuildParams{
-			Rule:        zip,
-			Description: "zip " + outputFile.Base(),
-			Inputs:      covFiles,
-			Output:      outputFile,
-		})
-
-		return android.OptionalPathForPath(outputFile)
-	}
-	return android.OptionalPath{}
-}
diff --git a/rust/compiler.go b/rust/compiler.go
index bcea6cc..d45a5aa 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -136,8 +136,7 @@
 }
 
 type baseCompiler struct {
-	Properties   BaseCompilerProperties
-	coverageFile android.Path //rustc generates a single gcno file
+	Properties BaseCompilerProperties
 
 	// Install related
 	dir      string
@@ -147,8 +146,7 @@
 	path     android.InstallPath
 	location installLocation
 
-	coverageOutputZipFile android.OptionalPath
-	distFile              android.OptionalPath
+	distFile android.OptionalPath
 	// Stripped output file. If Valid(), this file will be installed instead of outputFile.
 	strippedOutputFile android.OptionalPath
 }
diff --git a/rust/coverage.go b/rust/coverage.go
index 26375f5..dac526a 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -20,7 +20,9 @@
 	"android/soong/cc"
 )
 
-var CovLibraryName = "libprofile-extras"
+var CovLibraryName = "libprofile-clang-extras"
+
+const profileInstrFlag = "-fprofile-instr-generate=/data/misc/trace/clang-%p-%m.profraw"
 
 type coverage struct {
 	Properties cc.CoverageProperties
@@ -53,9 +55,9 @@
 		flags.Coverage = true
 		coverage := ctx.GetDirectDepWithTag(CovLibraryName, cc.CoverageDepTag).(cc.LinkableInterface)
 		flags.RustFlags = append(flags.RustFlags,
-			"-Z profile", "-g", "-C opt-level=0", "-C link-dead-code")
+			"-Z instrument-coverage", "-g", "-C link-dead-code")
 		flags.LinkFlags = append(flags.LinkFlags,
-			"--coverage", "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,getenv")
+			profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
 		deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
 	}
 
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index e7f873e..4b6c9d4 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -56,7 +56,7 @@
 	fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
 	buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
 
-	rustcCoverageFlags := []string{"-Z profile", " -g ", "-C opt-level=0", "-C link-dead-code"}
+	rustcCoverageFlags := []string{"-Z instrument-coverage", " -g ", "-C link-dead-code"}
 	for _, flag := range rustcCoverageFlags {
 		missingErrorStr := "missing rustc flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
 		containsErrorStr := "contains rustc flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
@@ -75,7 +75,7 @@
 		}
 	}
 
-	linkCoverageFlags := []string{"--coverage", " -g "}
+	linkCoverageFlags := []string{"-fprofile-instr-generate=/data/misc/trace/clang-%p-%m.profraw", " -g "}
 	for _, flag := range linkCoverageFlags {
 		missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
 		containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
@@ -96,83 +96,6 @@
 
 }
 
-// Test coverage files are included correctly
-func TestCoverageZip(t *testing.T) {
-	ctx := testRustCov(t, `
-		rust_library {
-			name: "libfoo",
-			srcs: ["foo.rs"],
-			rlibs: ["librlib"],
-			crate_name: "foo",
-		}
-                rust_ffi_static {
-                        name: "libbaz",
-                        srcs: ["foo.rs"],
-                        rlibs: ["librlib"],
-                        crate_name: "baz",
-                }
-		rust_library_rlib {
-			name: "librlib",
-			srcs: ["foo.rs"],
-			crate_name: "rlib",
-		}
-		rust_binary {
-			name: "fizz",
-			rlibs: ["librlib"],
-			static_libs: ["libbaz"],
-			srcs: ["foo.rs"],
-		}
-		cc_binary {
-			name: "buzz",
-			static_libs: ["libbaz"],
-			srcs: ["foo.c"],
-		}
-		cc_library {
-			name: "libbar",
-			static_libs: ["libbaz"],
-			compile_multilib: "64",
-			srcs: ["foo.c"],
-		}`)
-
-	fizzZipInputs := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("zip").Inputs.Strings()
-	libfooZipInputs := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib_cov").Rule("zip").Inputs.Strings()
-	buzzZipInputs := ctx.ModuleForTests("buzz", "android_arm64_armv8-a_cov").Rule("zip").Inputs.Strings()
-	libbarZipInputs := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared_cov").Rule("zip").Inputs.Strings()
-
-	// Make sure the expected number of input files are included.
-	if len(fizzZipInputs) != 3 {
-		t.Fatalf("expected only 3 coverage inputs for rust 'fizz' binary, got %#v: %#v", len(fizzZipInputs), fizzZipInputs)
-	}
-	if len(libfooZipInputs) != 2 {
-		t.Fatalf("expected only 2 coverage inputs for rust 'libfoo' library, got %#v: %#v", len(libfooZipInputs), libfooZipInputs)
-	}
-	if len(buzzZipInputs) != 2 {
-		t.Fatalf("expected only 2 coverage inputs for cc 'buzz' binary, got %#v: %#v", len(buzzZipInputs), buzzZipInputs)
-	}
-	if len(libbarZipInputs) != 2 {
-		t.Fatalf("expected only 2 coverage inputs for cc 'libbar' library, got %#v: %#v", len(libbarZipInputs), libbarZipInputs)
-	}
-
-	// Make sure the expected inputs are provided to the zip rule.
-	if !android.SuffixInList(fizzZipInputs, "android_arm64_armv8-a_rlib_dylib-std_cov/librlib.gcno") ||
-		!android.SuffixInList(fizzZipInputs, "android_arm64_armv8-a_static_cov/libbaz.gcno") ||
-		!android.SuffixInList(fizzZipInputs, "android_arm64_armv8-a_cov/fizz.gcno") {
-		t.Fatalf("missing expected coverage files for rust 'fizz' binary: %#v", fizzZipInputs)
-	}
-	if !android.SuffixInList(libfooZipInputs, "android_arm64_armv8-a_rlib_dylib-std_cov/librlib.gcno") ||
-		!android.SuffixInList(libfooZipInputs, "android_arm64_armv8-a_dylib_cov/libfoo.gcno") {
-		t.Fatalf("missing expected coverage files for rust 'fizz' binary: %#v", libfooZipInputs)
-	}
-	if !android.SuffixInList(buzzZipInputs, "android_arm64_armv8-a_cov/obj/foo.gcno") ||
-		!android.SuffixInList(buzzZipInputs, "android_arm64_armv8-a_static_cov/libbaz.gcno") {
-		t.Fatalf("missing expected coverage files for cc 'buzz' binary: %#v", buzzZipInputs)
-	}
-	if !android.SuffixInList(libbarZipInputs, "android_arm64_armv8-a_static_cov/obj/foo.gcno") ||
-		!android.SuffixInList(libbarZipInputs, "android_arm64_armv8-a_static_cov/libbaz.gcno") {
-		t.Fatalf("missing expected coverage files for cc 'libbar' library: %#v", libbarZipInputs)
-	}
-}
-
 func TestCoverageDeps(t *testing.T) {
 	ctx := testRustCov(t, `
 		rust_binary {
@@ -181,7 +104,7 @@
 		}`)
 
 	fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc")
-	if !strings.Contains(fizz.Args["linkFlags"], "libprofile-extras.a") {
-		t.Fatalf("missing expected coverage 'libprofile-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
+	if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
+		t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
 	}
 }
diff --git a/rust/library.go b/rust/library.go
index 4ac52b4..6433285 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -452,26 +452,22 @@
 		fileName = library.getStem(ctx) + ctx.toolchain().RlibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		outputs := TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
-		library.coverageFile = outputs.coverageFile
+		TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 	} else if library.dylib() {
 		fileName = library.getStem(ctx) + ctx.toolchain().DylibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		outputs := TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
-		library.coverageFile = outputs.coverageFile
+		TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 	} else if library.static() {
 		fileName = library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		outputs := TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
-		library.coverageFile = outputs.coverageFile
+		TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 	} else if library.shared() {
 		fileName = library.sharedLibFilename(ctx)
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
-		outputs := TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
-		library.coverageFile = outputs.coverageFile
+		TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 	}
 
 	if !library.rlib() && library.stripper.NeedsStrip(ctx) {
@@ -480,15 +476,6 @@
 		library.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
 	}
 
-	var coverageFiles android.Paths
-	if library.coverageFile != nil {
-		coverageFiles = append(coverageFiles, library.coverageFile)
-	}
-	if len(deps.coverageFiles) > 0 {
-		coverageFiles = append(coverageFiles, deps.coverageFiles...)
-	}
-	library.coverageOutputZipFile = TransformCoverageFilesToZip(ctx, coverageFiles, library.getStem(ctx))
-
 	if library.rlib() || library.dylib() {
 		library.flagExporter.exportLinkDirs(deps.linkDirs...)
 		library.flagExporter.exportDepFlags(deps.depFlags...)
diff --git a/rust/rust.go b/rust/rust.go
index 1fa97af..a2d0292 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -283,8 +283,6 @@
 	depGeneratedHeaders   android.Paths
 	depSystemIncludePaths android.Paths
 
-	coverageFiles android.Paths
-
 	CrtBegin android.OptionalPath
 	CrtEnd   android.OptionalPath
 
@@ -506,15 +504,7 @@
 
 func (mod *Module) CoverageFiles() android.Paths {
 	if mod.compiler != nil {
-		if !mod.compiler.nativeCoverage() {
-			return android.Paths{}
-		}
-		if library, ok := mod.compiler.(*libraryDecorator); ok {
-			if library.coverageFile != nil {
-				return android.Paths{library.coverageFile}
-			}
-			return android.Paths{}
-		}
+		return android.Paths{}
 	}
 	panic(fmt.Errorf("CoverageFiles called on non-library module: %q", mod.BaseModuleName()))
 }
@@ -817,7 +807,6 @@
 					ctx.ModuleErrorf("mod %q not an rlib library", depName+rustDep.Properties.SubName)
 					return
 				}
-				depPaths.coverageFiles = append(depPaths.coverageFiles, rustDep.CoverageFiles()...)
 				directRlibDeps = append(directRlibDeps, rustDep)
 				mod.Properties.AndroidMkRlibs = append(mod.Properties.AndroidMkRlibs, depName+rustDep.Properties.SubName)
 			case procMacroDepTag:
@@ -893,7 +882,6 @@
 				depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
 				depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
 				depPaths.depGeneratedHeaders = append(depPaths.depGeneratedHeaders, exportedInfo.GeneratedHeaders...)
-				depPaths.coverageFiles = append(depPaths.coverageFiles, ccDep.CoverageFiles()...)
 				directStaticLibDeps = append(directStaticLibDeps, ccDep)
 				mod.Properties.AndroidMkStaticLibs = append(mod.Properties.AndroidMkStaticLibs, depName)
 			case cc.IsSharedDepTag(depTag):
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 48c8d74..fc7f47e 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -134,7 +134,7 @@
 	if tctx.config == nil {
 		t.Fatalf("tctx.config not been generated yet. Please call generateConfig first.")
 	}
-	tctx.config.TestProductVariables.GcovCoverage = proptools.BoolPtr(true)
+	tctx.config.TestProductVariables.ClangCoverage = proptools.BoolPtr(true)
 	tctx.config.TestProductVariables.Native_coverage = proptools.BoolPtr(true)
 	tctx.config.TestProductVariables.NativeCoveragePaths = []string{"*"}
 }