Merge changes I94fd8bbc,I497dcdff,I1873a180

* changes:
  rust: strip libraries and binaries
  rust: add ccToolchain to Module
  rust: enable use-android-relr-tags
diff --git a/rust/Android.bp b/rust/Android.bp
index bbeb28d..ad2bbd8 100644
--- a/rust/Android.bp
+++ b/rust/Android.bp
@@ -20,6 +20,7 @@
         "proc_macro.go",
         "project_json.go",
         "rust.go",
+        "strip.go",
         "source_provider.go",
         "test.go",
         "testing.go",
diff --git a/rust/androidmk.go b/rust/androidmk.go
index fda0a25..10f10d8 100644
--- a/rust/androidmk.go
+++ b/rust/androidmk.go
@@ -96,7 +96,6 @@
 
 	ret.Class = "EXECUTABLES"
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
-		fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", binary.unstrippedOutputFile.String())
 		if binary.coverageOutputZipFile.Valid() {
 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE := "+binary.coverageOutputZipFile.String())
 		}
@@ -139,9 +138,6 @@
 	}
 
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
-		if !library.rlib() {
-			fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", library.unstrippedOutputFile.String())
-		}
 		if library.coverageOutputZipFile.Valid() {
 			fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE := "+library.coverageOutputZipFile.String())
 		}
@@ -180,12 +176,19 @@
 }
 
 func (compiler *baseCompiler) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
+	var unstrippedOutputFile android.OptionalPath
 	// Soong installation is only supported for host modules. Have Make
 	// installation trigger Soong installation.
 	if ctx.Target().Os.Class == android.Host {
 		ret.OutputFile = android.OptionalPathForPath(compiler.path)
+	} else if compiler.strippedOutputFile.Valid() {
+		unstrippedOutputFile = ret.OutputFile
+		ret.OutputFile = compiler.strippedOutputFile
 	}
 	ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
+		if compiler.strippedOutputFile.Valid() {
+			fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", unstrippedOutputFile)
+		}
 		path, file := filepath.Split(compiler.path.ToMakePath().String())
 		stem, suffix, _ := android.SplitFileExt(file)
 		fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+suffix)
diff --git a/rust/binary.go b/rust/binary.go
index d287a06..1d02453 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -28,6 +28,7 @@
 
 type binaryDecorator struct {
 	*baseCompiler
+	stripper Stripper
 
 	Properties BinaryCompilerProperties
 }
@@ -86,7 +87,8 @@
 
 func (binary *binaryDecorator) compilerProps() []interface{} {
 	return append(binary.baseCompiler.compilerProps(),
-		&binary.Properties)
+		&binary.Properties,
+		&binary.stripper.StripProperties)
 }
 
 func (binary *binaryDecorator) nativeCoverage() bool {
@@ -95,16 +97,20 @@
 
 func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
 	fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
-
 	srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
-
 	outputFile := android.PathForModuleOut(ctx, fileName)
-	binary.unstrippedOutputFile = outputFile
 
 	flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
 	flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
 
 	outputs := TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
+
+	if binary.stripper.NeedsStrip(ctx) {
+		strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
+		binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
+		binary.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
+	}
+
 	binary.coverageFile = outputs.coverageFile
 
 	var coverageFiles android.Paths
diff --git a/rust/binary_test.go b/rust/binary_test.go
index 2fc38ed..cfef57a 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -96,3 +96,33 @@
 		t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
 	}
 }
+
+// Test that stripped versions are correctly generated and used.
+func TestStrippedBinary(t *testing.T) {
+	ctx := testRust(t, `
+		rust_binary {
+			name: "foo",
+			srcs: ["foo.rs"],
+		}
+		rust_binary {
+			name: "bar",
+			srcs: ["foo.rs"],
+			strip: {
+				none: true
+			}
+		}
+	`)
+
+	foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a")
+	foo.Output("stripped/foo")
+	// Check that the `cp` rules is using the stripped version as input.
+	cp := foo.Rule("android.Cp")
+	if !strings.HasSuffix(cp.Input.String(), "stripped/foo") {
+		t.Errorf("installed binary not based on stripped version: %v", cp.Input)
+	}
+
+	fizzBar := ctx.ModuleForTests("bar", "android_arm64_armv8-a").MaybeOutput("stripped/bar")
+	if fizzBar.Rule != nil {
+		t.Errorf("stripped version of bar has been generated")
+	}
+}
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 9b09e61..3f7a6ce 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -21,7 +21,6 @@
 	"github.com/google/blueprint/proptools"
 
 	"android/soong/android"
-	ccConfig "android/soong/cc/config"
 )
 
 var (
@@ -92,8 +91,8 @@
 	Properties BindgenProperties
 }
 
-func (b *bindgenDecorator) GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
-	ccToolchain := ccConfig.FindToolchain(ctx.Os(), ctx.Arch())
+func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
+	ccToolchain := ctx.RustModule().ccToolchain(ctx)
 
 	var cflags []string
 	var implicits android.Paths
diff --git a/rust/compiler.go b/rust/compiler.go
index 2600f4d..ddf1fac 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -129,8 +129,9 @@
 	location installLocation
 
 	coverageOutputZipFile android.OptionalPath
-	unstrippedOutputFile  android.Path
 	distFile              android.OptionalPath
+	// Stripped output file. If Valid(), this file will be installed instead of outputFile.
+	strippedOutputFile android.OptionalPath
 }
 
 func (compiler *baseCompiler) Disabled() bool {
@@ -269,8 +270,12 @@
 	return false
 }
 
-func (compiler *baseCompiler) install(ctx ModuleContext, file android.Path) {
-	compiler.path = ctx.InstallFile(compiler.installDir(ctx), file.Base(), file)
+func (compiler *baseCompiler) install(ctx ModuleContext) {
+	path := ctx.RustModule().outputFile
+	if compiler.strippedOutputFile.Valid() {
+		path = compiler.strippedOutputFile
+	}
+	compiler.path = ctx.InstallFile(compiler.installDir(ctx), path.Path().Base(), path.Path())
 }
 
 func (compiler *baseCompiler) getStem(ctx ModuleContext) string {
diff --git a/rust/config/global.go b/rust/config/global.go
index 97de676..88d4139 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -52,6 +52,7 @@
 		"-Wl,--fatal-warnings",
 
 		"-Wl,--pack-dyn-relocs=android+relr",
+		"-Wl,--use-android-relr-tags",
 		"-Wl,--no-undefined",
 		"-Wl,--hash-style=gnu",
 
diff --git a/rust/library.go b/rust/library.go
index 450c9d4..a442933 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -78,6 +78,7 @@
 type libraryDecorator struct {
 	*baseCompiler
 	*flagExporter
+	stripper Stripper
 
 	Properties        LibraryCompilerProperties
 	MutatedProperties LibraryMutatedProperties
@@ -338,7 +339,8 @@
 func (library *libraryDecorator) compilerProps() []interface{} {
 	return append(library.baseCompiler.compilerProps(),
 		&library.Properties,
-		&library.MutatedProperties)
+		&library.MutatedProperties,
+		&library.stripper.StripProperties)
 }
 
 func (library *libraryDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps {
@@ -371,7 +373,8 @@
 }
 
 func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) android.Path {
-	var outputFile android.WritablePath
+	var outputFile android.ModuleOutPath
+	var fileName string
 	var srcPath android.Path
 
 	if library.sourceProvider != nil {
@@ -391,31 +394,37 @@
 	}
 
 	if library.rlib() {
-		fileName := library.getStem(ctx) + ctx.toolchain().RlibSuffix()
+		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
 	} else if library.dylib() {
-		fileName := library.getStem(ctx) + ctx.toolchain().DylibSuffix()
+		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
 	} else if library.static() {
-		fileName := library.getStem(ctx) + ctx.toolchain().StaticLibSuffix()
+		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
 	} else if library.shared() {
-		fileName := library.sharedLibFilename(ctx)
+		fileName = library.sharedLibFilename(ctx)
 		outputFile = android.PathForModuleOut(ctx, fileName)
 
 		outputs := TransformSrctoShared(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 		library.coverageFile = outputs.coverageFile
 	}
 
+	if !library.rlib() && library.stripper.NeedsStrip(ctx) {
+		strippedOutputFile := android.PathForModuleOut(ctx, "stripped", fileName)
+		library.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile)
+		library.strippedOutputFile = android.OptionalPathForPath(strippedOutputFile)
+	}
+
 	var coverageFiles android.Paths
 	if library.coverageFile != nil {
 		coverageFiles = append(coverageFiles, library.coverageFile)
@@ -430,7 +439,6 @@
 		library.exportDepFlags(deps.depFlags...)
 		library.exportLinkObjects(deps.linkObjects...)
 	}
-	library.unstrippedOutputFile = outputFile
 
 	return outputFile
 }
diff --git a/rust/library_test.go b/rust/library_test.go
index 0fd9e32..f1bc050 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -206,3 +206,35 @@
 
 	}
 }
+
+// Test that stripped versions are correctly generated and used.
+func TestStrippedLibrary(t *testing.T) {
+	ctx := testRust(t, `
+		rust_library_dylib {
+			name: "libfoo",
+			crate_name: "foo",
+			srcs: ["foo.rs"],
+		}
+		rust_library_dylib {
+			name: "libbar",
+			crate_name: "bar",
+			srcs: ["foo.rs"],
+			strip: {
+				none: true
+			}
+		}
+	`)
+
+	foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_dylib")
+	foo.Output("stripped/libfoo.dylib.so")
+	// Check that the `cp` rule is using the stripped version as input.
+	cp := foo.Rule("android.Cp")
+	if !strings.HasSuffix(cp.Input.String(), "stripped/libfoo.dylib.so") {
+		t.Errorf("installed binary not based on stripped version: %v", cp.Input)
+	}
+
+	fizzBar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_dylib").MaybeOutput("stripped/libbar.dylib.so")
+	if fizzBar.Rule != nil {
+		t.Errorf("stripped version of bar has been generated")
+	}
+}
diff --git a/rust/prebuilt.go b/rust/prebuilt.go
index 3d081c1..f9c8934 100644
--- a/rust/prebuilt.go
+++ b/rust/prebuilt.go
@@ -99,9 +99,6 @@
 	if len(paths) > 0 {
 		ctx.PropertyErrorf("srcs", "prebuilt libraries can only have one entry in srcs (the prebuilt path)")
 	}
-
-	prebuilt.unstrippedOutputFile = srcPath
-
 	return srcPath
 }
 
diff --git a/rust/proc_macro.go b/rust/proc_macro.go
index 748879c..0c6ec99 100644
--- a/rust/proc_macro.go
+++ b/rust/proc_macro.go
@@ -66,9 +66,6 @@
 	outputFile := android.PathForModuleOut(ctx, fileName)
 
 	srcPath, _ := srcPathFromModuleSrcs(ctx, procMacro.baseCompiler.Properties.Srcs)
-
-	procMacro.unstrippedOutputFile = outputFile
-
 	TransformSrctoProcMacro(ctx, srcPath, deps, flags, outputFile, deps.linkDirs)
 	return outputFile
 }
diff --git a/rust/rust.go b/rust/rust.go
index 68dc5a0..84728df 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -23,6 +23,7 @@
 
 	"android/soong/android"
 	"android/soong/cc"
+	cc_config "android/soong/cc/config"
 	"android/soong/rust/config"
 )
 
@@ -283,7 +284,7 @@
 	crateName() string
 
 	inData() bool
-	install(ctx ModuleContext, path android.Path)
+	install(ctx ModuleContext)
 	relativeInstallPath() string
 
 	nativeCoverage() bool
@@ -656,6 +657,10 @@
 	return mod.cachedToolchain
 }
 
+func (mod *Module) ccToolchain(ctx android.BaseModuleContext) cc_config.Toolchain {
+	return cc_config.FindToolchain(ctx.Os(), ctx.Arch())
+}
+
 func (d *Defaults) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 }
 
@@ -699,7 +704,7 @@
 
 		mod.outputFile = android.OptionalPathForPath(outputFile)
 		if mod.outputFile.Valid() && !mod.Properties.PreventInstall {
-			mod.compiler.install(ctx, mod.outputFile.Path())
+			mod.compiler.install(ctx)
 		}
 	}
 }
diff --git a/rust/source_provider.go b/rust/source_provider.go
index e168718..755a369 100644
--- a/rust/source_provider.go
+++ b/rust/source_provider.go
@@ -38,7 +38,7 @@
 var _ SourceProvider = (*BaseSourceProvider)(nil)
 
 type SourceProvider interface {
-	GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path
+	GenerateSource(ctx ModuleContext, deps PathDeps) android.Path
 	Srcs() android.Paths
 	SourceProviderProps() []interface{}
 	SourceProviderDeps(ctx DepsContext, deps Deps) Deps
@@ -49,7 +49,7 @@
 	return android.Paths{sp.OutputFile}
 }
 
-func (sp *BaseSourceProvider) GenerateSource(ctx android.ModuleContext, deps PathDeps) android.Path {
+func (sp *BaseSourceProvider) GenerateSource(ctx ModuleContext, deps PathDeps) android.Path {
 	panic("BaseSourceProviderModule does not implement GenerateSource()")
 }
 
diff --git a/rust/strip.go b/rust/strip.go
new file mode 100644
index 0000000..d1bbba6
--- /dev/null
+++ b/rust/strip.go
@@ -0,0 +1,30 @@
+// Copyright 2020 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 rust
+
+import (
+	"android/soong/android"
+	"android/soong/cc"
+)
+
+// Stripper encapsulates cc.Stripper.
+type Stripper struct {
+	cc.Stripper
+}
+
+func (s *Stripper) StripExecutableOrSharedLib(ctx ModuleContext, in android.Path, out android.ModuleOutPath) {
+	ccFlags := cc.StripFlags{Toolchain: ctx.RustModule().ccToolchain(ctx)}
+	s.Stripper.StripExecutableOrSharedLib(ctx, in, out, ccFlags)
+}
diff --git a/rust/test.go b/rust/test.go
index 19802e3..d93fc31 100644
--- a/rust/test.go
+++ b/rust/test.go
@@ -88,7 +88,7 @@
 	return append(test.binaryDecorator.compilerProps(), &test.Properties)
 }
 
-func (test *testDecorator) install(ctx ModuleContext, file android.Path) {
+func (test *testDecorator) install(ctx ModuleContext) {
 	test.testConfig = tradefed.AutoGenRustTestConfig(ctx,
 		test.Properties.Test_config,
 		test.Properties.Test_config_template,
@@ -103,7 +103,7 @@
 		ctx.PropertyErrorf("no_named_install_directory", "Module install directory may only be disabled if relative_install_path is set")
 	}
 
-	test.binaryDecorator.install(ctx, file)
+	test.binaryDecorator.install(ctx)
 }
 
 func (test *testDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {