rust: Add support for bootstrap linker.

Adds the 'bootstrap' property to Rust modules to set the linker to the
bootstrap linker.

Bug: 194276829
Test: set bootstrap: true on module, checked .interp section on output.
Test: bootstrapped binary runs.
Change-Id: I459c8194902cfea3c44b060e70d28a43fcba3ade
diff --git a/rust/binary_test.go b/rust/binary_test.go
index 86f50d3..968c0c1 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -114,6 +114,23 @@
 	}
 }
 
+// Test that the bootstrap property sets the appropriate linker
+func TestBootstrap(t *testing.T) {
+	ctx := testRust(t, `
+		rust_binary {
+			name: "foo",
+			srcs: ["foo.rs"],
+			bootstrap: true,
+		}`)
+
+	foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
+
+	flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
+	if !strings.Contains(foo.Args["linkFlags"], flag) {
+		t.Errorf("missing link flag to use bootstrap linker, expecting %#v, linkFlags: %#v", flag, foo.Args["linkFlags"])
+	}
+}
+
 func TestStaticBinaryFlags(t *testing.T) {
 	ctx := testRust(t, `
 		rust_binary {
diff --git a/rust/builder.go b/rust/builder.go
index 6db508d..523428d 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -220,6 +220,15 @@
 	linkFlags = append(linkFlags, flags.GlobalLinkFlags...)
 	linkFlags = append(linkFlags, flags.LinkFlags...)
 
+	// Check if this module needs to use the bootstrap linker
+	if ctx.RustModule().Bootstrap() && !ctx.RustModule().InRecovery() && !ctx.RustModule().InRamdisk() && !ctx.RustModule().InVendorRamdisk() {
+		dynamicLinker := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker"
+		if ctx.toolchain().Is64Bit() {
+			dynamicLinker += "64"
+		}
+		linkFlags = append(linkFlags, dynamicLinker)
+	}
+
 	libFlags := makeLibFlags(deps)
 
 	// Collect dependencies
diff --git a/rust/rust.go b/rust/rust.go
index 52b4094..931cb9d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -85,6 +85,10 @@
 	VendorRamdiskVariantNeeded bool     `blueprint:"mutated"`
 	ExtraVariants              []string `blueprint:"mutated"`
 
+	// Allows this module to use non-APEX version of libraries. Useful
+	// for building binaries that are started before APEXes are activated.
+	Bootstrap *bool
+
 	// Used by vendor snapshot to record dependencies from snapshot modules.
 	SnapshotSharedLibs []string `blueprint:"mutated"`
 	SnapshotStaticLibs []string `blueprint:"mutated"`
@@ -288,7 +292,7 @@
 }
 
 func (mod *Module) Bootstrap() bool {
-	return false
+	return Bool(mod.Properties.Bootstrap)
 }
 
 func (mod *Module) MustUseVendorVariant() bool {