Merge changes I46e851c8,I2c9eb248

* changes:
  rust: Add HWASan build support
  Export CC HWASan sanitizer type
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 5ac6924..28c0e53 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -69,6 +69,10 @@
 	// Returns the results of GetOutputFiles and GetCcObjectFiles in a single query (in that order).
 	GetOutputFilesAndCcObjectFiles(label string, archType ArchType) ([]string, []string, bool)
 
+	// GetPrebuiltCcStaticLibraryFiles returns paths to prebuilt cc static libraries, and whether the
+	// results were available
+	GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool)
+
 	// ** End cquery methods
 
 	// Issues commands to Bazel to receive results for all cquery requests
@@ -126,6 +130,11 @@
 	return result, result, ok
 }
 
+func (m MockBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
+	result, ok := m.AllFiles[label]
+	return result, ok
+}
+
 func (m MockBazelContext) InvokeBazel() error {
 	panic("unimplemented")
 }
@@ -169,6 +178,19 @@
 	return outputFiles, ccObjects, ok
 }
 
+// GetPrebuiltCcStaticLibraryFiles returns a slice of prebuilt static libraries for the given
+// label/archType if there are query results; otherwise, it enqueues the query and returns false.
+func (bazelCtx *bazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
+	result, ok := bazelCtx.cquery(label, cquery.GetPrebuiltCcStaticLibraryFiles, archType)
+	if !ok {
+		return nil, false
+	}
+
+	bazelOutput := strings.TrimSpace(result)
+	ret := cquery.GetPrebuiltCcStaticLibraryFiles.ParseResult(bazelOutput)
+	return ret, ok
+}
+
 func (n noopBazelContext) GetOutputFiles(label string, archType ArchType) ([]string, bool) {
 	panic("unimplemented")
 }
@@ -177,6 +199,10 @@
 	panic("unimplemented")
 }
 
+func (n noopBazelContext) GetPrebuiltCcStaticLibraryFiles(label string, archType ArchType) ([]string, bool) {
+	panic("unimplemented")
+}
+
 func (n noopBazelContext) InvokeBazel() error {
 	panic("unimplemented")
 }
diff --git a/android/config.go b/android/config.go
index cfbc37f..80651bb 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1498,6 +1498,10 @@
 	return c.config.productVariables.BuildBrokenTrebleSyspropNeverallow
 }
 
+func (c *deviceConfig) BuildDebugfsRestrictionsEnabled() bool {
+	return c.config.productVariables.BuildDebugfsRestrictionsEnabled
+}
+
 func (c *deviceConfig) BuildBrokenVendorPropertyNamespace() bool {
 	return c.config.productVariables.BuildBrokenVendorPropertyNamespace
 }
diff --git a/android/variable.go b/android/variable.go
index dff48c2..f25143d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -385,6 +385,8 @@
 	BuildBrokenTrebleSyspropNeverallow bool `json:",omitempty"`
 	BuildBrokenVendorPropertyNamespace bool `json:",omitempty"`
 
+	BuildDebugfsRestrictionsEnabled bool `json:",omitempty"`
+
 	RequiresInsecureExecmemForSwiftshader bool `json:",omitempty"`
 
 	SelinuxIgnoreNeverallows bool `json:",omitempty"`
diff --git a/apex/apex.go b/apex/apex.go
index bad382a..880028f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1927,6 +1927,10 @@
 						filesInfo = append(filesInfo, af)
 						return true // track transitive dependencies
 					}
+				} else if rust.IsRlibDepTag(depTag) {
+					// Rlib is statically linked, but it might have shared lib
+					// dependencies. Track them.
+					return true
 				} else if java.IsbootImageContentDepTag(depTag) {
 					// Add the contents of the boot image to the apex.
 					switch child.(type) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 88aa5f9..5439265 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -392,6 +392,15 @@
 			srcs: ["foo.rs"],
 			crate_name: "foo",
 			apex_available: ["myapex"],
+			shared_libs: ["libfoo.shared_from_rust"],
+		}
+
+		cc_library_shared {
+			name: "libfoo.shared_from_rust",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			apex_available: ["myapex"],
 		}
 
 		rust_library_dylib {
@@ -539,6 +548,7 @@
 	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.rlib.rust"), "android_arm64_armv8-a_rlib_dylib-std_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.dylib.rust"), "android_arm64_armv8-a_dylib_apex10000")
 	ensureListContains(t, ctx.ModuleVariantsForTests("libbar.ffi"), "android_arm64_armv8-a_shared_apex10000")
+	ensureListContains(t, ctx.ModuleVariantsForTests("libfoo.shared_from_rust"), "android_arm64_armv8-a_shared_apex10000")
 
 	// Ensure that both direct and indirect deps are copied into apex
 	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
@@ -548,6 +558,7 @@
 	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.dylib.rust.dylib.so")
 	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.ffi.so")
 	ensureContains(t, copyCmds, "image.apex/lib64/libbar.ffi.so")
+	ensureContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
 	// .. but not for java libs
 	ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
 	ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index 4a64c51..b88da2f 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -5,8 +5,9 @@
 )
 
 var (
-	GetOutputFiles                 = &getOutputFilesRequestType{}
-	GetOutputFilesAndCcObjectFiles = &getOutputFilesAndCcObjectFilesType{}
+	GetOutputFiles                  = &getOutputFilesRequestType{}
+	GetOutputFilesAndCcObjectFiles  = &getOutputFilesAndCcObjectFilesType{}
+	GetPrebuiltCcStaticLibraryFiles = &getPrebuiltCcStaticLibraryFiles{}
 )
 
 type GetOutputFilesAndCcObjectFiles_Result struct {
@@ -86,6 +87,34 @@
 	return GetOutputFilesAndCcObjectFiles_Result{outputFiles, ccObjects}
 }
 
+type getPrebuiltCcStaticLibraryFiles struct{}
+
+// Name returns the name of the starlark function to get prebuilt cc static library files
+func (g getPrebuiltCcStaticLibraryFiles) Name() string {
+	return "getPrebuiltCcStaticLibraryFiles"
+}
+
+// StarlarkFunctionBody returns the unindented body of a starlark function for extracting the static
+// library paths from a cc_import module.
+func (g getPrebuiltCcStaticLibraryFiles) StarlarkFunctionBody() string {
+	return `
+linker_inputs = providers(target)["CcInfo"].linking_context.linker_inputs.to_list()
+
+static_libraries = []
+for linker_input in linker_inputs:
+  for library in linker_input.libraries:
+    static_libraries.append(library.static_library.path)
+
+return ', '.join(static_libraries)`
+}
+
+// ParseResult returns a slice of bazel output paths to static libraries if any exist for the given
+// rawString corresponding to the string output which was created by evaluating the
+// StarlarkFunctionBody.
+func (g getPrebuiltCcStaticLibraryFiles) ParseResult(rawString string) []string {
+	return strings.Split(rawString, ", ")
+}
+
 // splitOrEmpty is a modification of strings.Split() that returns an empty list
 // if the given string is empty.
 func splitOrEmpty(s string, sep string) []string {
diff --git a/bloaty/bloaty.go b/bloaty/bloaty.go
index 653c489..764cded 100644
--- a/bloaty/bloaty.go
+++ b/bloaty/bloaty.go
@@ -23,7 +23,7 @@
 )
 
 const bloatyDescriptorExt = ".bloaty.csv"
-const protoFilename = "binary_sizes.pb"
+const protoFilename = "binary_sizes.pb.gz"
 
 var (
 	fileSizeMeasurerKey blueprint.ProviderKey
diff --git a/bloaty/bloaty_merger.py b/bloaty/bloaty_merger.py
index c873fb8..1034462 100644
--- a/bloaty/bloaty_merger.py
+++ b/bloaty/bloaty_merger.py
@@ -16,12 +16,13 @@
 Merges a list of .csv files from Bloaty into a protobuf.  It takes the list as
 a first argument and the output as second. For instance:
 
-    $ bloaty_merger binary_sizes.lst binary_sizes.pb
+    $ bloaty_merger binary_sizes.lst binary_sizes.pb.gz
 
 """
 
 import argparse
 import csv
+import gzip
 
 import ninja_rsp
 
@@ -57,7 +58,8 @@
   Args:
     input_list: The path to the file which contains the list of CSV files. Each
         filepath is separated by a space.
-    output_proto: The path for the output protobuf.
+    output_proto: The path for the output protobuf. It will be compressed using
+        gzip.
   """
   metrics = file_sections_pb2.FileSizeMetrics()
   reader = ninja_rsp.NinjaRspFileReader(input_list)
@@ -65,7 +67,7 @@
     file_proto = parse_csv(csv_path)
     if file_proto:
       metrics.files.append(file_proto)
-  with open(output_proto, "wb") as output:
+  with gzip.open(output_proto, "wb") as output:
     output.write(metrics.SerializeToString())
 
 def main():
diff --git a/bloaty/bloaty_merger_test.py b/bloaty/bloaty_merger_test.py
index 0e3641d..9de049a 100644
--- a/bloaty/bloaty_merger_test.py
+++ b/bloaty/bloaty_merger_test.py
@@ -11,6 +11,7 @@
 # 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.
+import gzip
 import unittest
 
 from pyfakefs import fake_filesystem_unittest
@@ -53,10 +54,10 @@
     self.fs.create_file("file1.bloaty.csv", contents=file1_content)
     self.fs.create_file("file2.bloaty.csv", contents=file2_content)
 
-    bloaty_merger.create_file_size_metrics("files.lst", "output.pb")
+    bloaty_merger.create_file_size_metrics("files.lst", "output.pb.gz")
 
     metrics = file_sections_pb2.FileSizeMetrics()
-    with open("output.pb", "rb") as output:
+    with gzip.open("output.pb.gz", "rb") as output:
       metrics.ParseFromString(output.read())
 
 
diff --git a/cc/builder.go b/cc/builder.go
index 8c9743f..da8501c 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -132,7 +132,7 @@
 		blueprint.RuleParams{
 			Depfile:     "${out}.d",
 			Deps:        blueprint.DepsGCC,
-			Command:     "CROSS_COMPILE=$crossCompile XZ=$xzCmd CLANG_BIN=${config.ClangBin} $stripPath ${args} -i ${in} -o ${out} -d ${out}.d",
+			Command:     "XZ=$xzCmd CLANG_BIN=${config.ClangBin} $stripPath ${args} -i ${in} -o ${out} -d ${out}.d",
 			CommandDeps: []string{"$stripPath", "$xzCmd"},
 			Pool:        darwinStripPool,
 		},
diff --git a/cc/prebuilt.go b/cc/prebuilt.go
index 6b9a3d5..3829b1e 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -305,6 +305,7 @@
 func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
 	module, library := NewPrebuiltLibrary(hod)
 	library.BuildOnlyStatic()
+	module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library}
 	return module, library
 }
 
@@ -319,6 +320,52 @@
 	properties prebuiltObjectProperties
 }
 
+type prebuiltStaticLibraryBazelHandler struct {
+	bazelHandler
+
+	module  *Module
+	library *libraryDecorator
+}
+
+func (h *prebuiltStaticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool {
+	bazelCtx := ctx.Config().BazelContext
+	staticLibs, ok := bazelCtx.GetPrebuiltCcStaticLibraryFiles(label, ctx.Arch().ArchType)
+	if !ok {
+		return false
+	}
+	if len(staticLibs) > 1 {
+		ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
+		return false
+	}
+
+	// TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags
+
+	// TODO(eakammer):Add stub-related flags if this library is a stub library.
+	// h.library.exportVersioningMacroIfNeeded(ctx)
+
+	// Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
+	// validation will fail. For now, set this to an empty list.
+	// TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
+	h.library.collectedSnapshotHeaders = android.Paths{}
+
+	if len(staticLibs) == 0 {
+		h.module.outputFile = android.OptionalPath{}
+		return true
+	}
+
+	out := android.PathForBazelOut(ctx, staticLibs[0])
+	h.module.outputFile = android.OptionalPathForPath(out)
+
+	depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(out).Build()
+	ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
+		StaticLibrary: out,
+
+		TransitiveStaticLibrariesForOrdering: depSet,
+	})
+
+	return true
+}
+
 func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
 	return &p.Prebuilt
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 69b03f9..397121e 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1080,6 +1080,12 @@
 			if Bool(c.sanitize.Properties.Sanitize.Diag.Memtag_heap) {
 				noteDep = "note_memtag_heap_sync"
 			}
+			// If we're using snapshots, redirect to snapshot whenever possible
+			// TODO(b/178470649): clean manual snapshot redirections
+			snapshot := mctx.Provider(SnapshotInfoProvider).(SnapshotInfo)
+			if lib, ok := snapshot.StaticLibs[noteDep]; ok {
+				noteDep = lib
+			}
 			depTag := libraryDependencyTag{Kind: staticLibraryDependency, wholeStatic: true}
 			variations := append(mctx.Target().Variations(),
 				blueprint.Variation{Mutator: "link", Variation: "static"})
diff --git a/cc/stl.go b/cc/stl.go
index 594231d..4f8865f 100644
--- a/cc/stl.go
+++ b/cc/stl.go
@@ -140,6 +140,17 @@
 }
 
 func staticUnwinder(ctx android.BaseModuleContext) string {
+	vndkVersion := ctx.Module().(*Module).VndkVersion()
+
+	// Modules using R vndk use different unwinder
+	if vndkVersion == "30" {
+		if ctx.Arch().ArchType == android.Arm {
+			return "libunwind_llvm"
+		} else {
+			return "libgcc_stripped"
+		}
+	}
+
 	return "libunwind"
 }
 
diff --git a/cc/vendor_snapshot_test.go b/cc/vendor_snapshot_test.go
index 8f77c28..1c3f1b4 100644
--- a/cc/vendor_snapshot_test.go
+++ b/cc/vendor_snapshot_test.go
@@ -334,7 +334,7 @@
 	vndkBp := `
 	vndk_prebuilt_shared {
 		name: "libvndk",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		vendor_available: true,
 		product_available: true,
@@ -378,7 +378,7 @@
 	// different arch snapshot which has to be ignored
 	vndk_prebuilt_shared {
 		name: "libvndk",
-		version: "28",
+		version: "30",
 		target_arch: "arm",
 		vendor_available: true,
 		product_available: true,
@@ -429,7 +429,7 @@
 		vendor: true,
 		nocrt: true,
 		no_libcrt: true,
-		stl: "none",
+		stl: "libc++_static",
 		system_shared_libs: [],
 		static_libs: ["libvndk"],
 		srcs: ["bin.cpp"],
@@ -437,13 +437,16 @@
 
 	vendor_snapshot {
 		name: "vendor_snapshot",
-		version: "28",
+		version: "30",
 		arch: {
 			arm64: {
 				vndk_libs: [
 					"libvndk",
 				],
 				static_libs: [
+					"libc++_static",
+					"libc++demangle",
+					"libgcc_stripped",
 					"libvendor",
 					"libvendor_available",
 					"libvndk",
@@ -482,7 +485,7 @@
 
 	vendor_snapshot_static {
 		name: "libvndk",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "both",
 		vendor: true,
@@ -500,7 +503,7 @@
 
 	vendor_snapshot_shared {
 		name: "libvendor",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "both",
 		vendor: true,
@@ -523,7 +526,7 @@
 
 	vendor_snapshot_static {
 		name: "lib32",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "32",
 		vendor: true,
@@ -536,7 +539,7 @@
 
 	vendor_snapshot_shared {
 		name: "lib32",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "32",
 		vendor: true,
@@ -549,7 +552,7 @@
 
 	vendor_snapshot_static {
 		name: "lib64",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "64",
 		vendor: true,
@@ -562,7 +565,7 @@
 
 	vendor_snapshot_shared {
 		name: "lib64",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "64",
 		vendor: true,
@@ -575,7 +578,7 @@
 
 	vendor_snapshot_static {
 		name: "libvendor",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "both",
 		vendor: true,
@@ -593,7 +596,7 @@
 
 	vendor_snapshot_shared {
 		name: "libvendor_available",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "both",
 		vendor: true,
@@ -611,7 +614,7 @@
 
 	vendor_snapshot_static {
 		name: "libvendor_available",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "both",
 		vendor: true,
@@ -627,9 +630,48 @@
 		},
 	}
 
+	vendor_snapshot_static {
+		name: "libc++_static",
+		version: "30",
+		target_arch: "arm64",
+		compile_multilib: "64",
+		vendor: true,
+		arch: {
+			arm64: {
+				src: "libc++_static.a",
+			},
+		},
+	}
+
+	vendor_snapshot_static {
+		name: "libc++demangle",
+		version: "30",
+		target_arch: "arm64",
+		compile_multilib: "64",
+		vendor: true,
+		arch: {
+			arm64: {
+				src: "libc++demangle.a",
+			},
+		},
+	}
+
+	vendor_snapshot_static {
+		name: "libgcc_stripped",
+		version: "30",
+		target_arch: "arm64",
+		compile_multilib: "64",
+		vendor: true,
+		arch: {
+			arm64: {
+				src: "libgcc_stripped.a",
+			},
+		},
+	}
+
 	vendor_snapshot_binary {
 		name: "bin",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "64",
 		vendor: true,
@@ -642,7 +684,7 @@
 
 	vendor_snapshot_binary {
 		name: "bin32",
-		version: "28",
+		version: "30",
 		target_arch: "arm64",
 		compile_multilib: "32",
 		vendor: true,
@@ -670,7 +712,7 @@
 	// different arch snapshot which has to be ignored
 	vendor_snapshot_binary {
 		name: "bin",
-		version: "28",
+		version: "30",
 		target_arch: "arm",
 		compile_multilib: "first",
 		vendor: true,
@@ -686,6 +728,7 @@
 	mockFS := map[string][]byte{
 		"deps/Android.bp":              []byte(depsBp),
 		"framework/Android.bp":         []byte(frameworkBp),
+		"framework/symbol.txt":         nil,
 		"vendor/Android.bp":            []byte(vendorProprietaryBp),
 		"vendor/bin":                   nil,
 		"vendor/bin32":                 nil,
@@ -693,6 +736,9 @@
 		"vendor/client.cpp":            nil,
 		"vendor/include/libvndk/a.h":   nil,
 		"vendor/include/libvendor/b.h": nil,
+		"vendor/libc++_static.a":       nil,
+		"vendor/libc++demangle.a":      nil,
+		"vendor/libgcc_striped.a":      nil,
 		"vendor/libvndk.a":             nil,
 		"vendor/libvendor.a":           nil,
 		"vendor/libvendor.so":          nil,
@@ -706,8 +752,8 @@
 	}
 
 	config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
-	config.TestProductVariables.DeviceVndkVersion = StringPtr("28")
-	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
+	config.TestProductVariables.DeviceVndkVersion = StringPtr("30")
+	config.TestProductVariables.Platform_vndk_version = StringPtr("31")
 	ctx := CreateTestContext(config)
 	ctx.Register()
 
@@ -716,14 +762,14 @@
 	_, errs = ctx.PrepareBuildActions(config)
 	android.FailIfErrored(t, errs)
 
-	sharedVariant := "android_vendor.28_arm64_armv8-a_shared"
-	staticVariant := "android_vendor.28_arm64_armv8-a_static"
-	binaryVariant := "android_vendor.28_arm64_armv8-a"
+	sharedVariant := "android_vendor.30_arm64_armv8-a_shared"
+	staticVariant := "android_vendor.30_arm64_armv8-a_static"
+	binaryVariant := "android_vendor.30_arm64_armv8-a"
 
-	shared32Variant := "android_vendor.28_arm_armv7-a-neon_shared"
-	binary32Variant := "android_vendor.28_arm_armv7-a-neon"
+	shared32Variant := "android_vendor.30_arm_armv7-a-neon_shared"
+	binary32Variant := "android_vendor.30_arm_armv7-a-neon"
 
-	// libclient uses libvndk.vndk.28.arm64, libvendor.vendor_static.28.arm64, libvendor_without_snapshot
+	// libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
 	libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
 	for _, includeFlags := range []string{
 		"-Ivndk/include/libvndk",     // libvndk
@@ -737,8 +783,8 @@
 
 	libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
 	for _, input := range [][]string{
-		[]string{sharedVariant, "libvndk.vndk.28.arm64"},
-		[]string{staticVariant, "libvendor.vendor_static.28.arm64"},
+		[]string{sharedVariant, "libvndk.vndk.30.arm64"},
+		[]string{staticVariant, "libvendor.vendor_static.30.arm64"},
 		[]string{staticVariant, "libvendor_without_snapshot"},
 	} {
 		outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
@@ -762,7 +808,7 @@
 		t.Errorf("wanted libclient32 AndroidMkSharedLibs %q, got %q", w, g)
 	}
 
-	// bin_without_snapshot uses libvndk.vendor_static.28.arm64
+	// bin_without_snapshot uses libvndk.vendor_static.30.arm64
 	binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
 	if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
 		t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
@@ -770,37 +816,37 @@
 	}
 
 	binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
-	libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.28.arm64"})
+	libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
 	if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
 		t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
 			libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
 	}
 
-	// libvendor.so is installed by libvendor.vendor_shared.28.arm64
-	ctx.ModuleForTests("libvendor.vendor_shared.28.arm64", sharedVariant).Output("libvendor.so")
+	// libvendor.so is installed by libvendor.vendor_shared.30.arm64
+	ctx.ModuleForTests("libvendor.vendor_shared.30.arm64", sharedVariant).Output("libvendor.so")
 
-	// lib64.so is installed by lib64.vendor_shared.28.arm64
-	ctx.ModuleForTests("lib64.vendor_shared.28.arm64", sharedVariant).Output("lib64.so")
+	// lib64.so is installed by lib64.vendor_shared.30.arm64
+	ctx.ModuleForTests("lib64.vendor_shared.30.arm64", sharedVariant).Output("lib64.so")
 
-	// lib32.so is installed by lib32.vendor_shared.28.arm64
-	ctx.ModuleForTests("lib32.vendor_shared.28.arm64", shared32Variant).Output("lib32.so")
+	// lib32.so is installed by lib32.vendor_shared.30.arm64
+	ctx.ModuleForTests("lib32.vendor_shared.30.arm64", shared32Variant).Output("lib32.so")
 
-	// libvendor_available.so is installed by libvendor_available.vendor_shared.28.arm64
-	ctx.ModuleForTests("libvendor_available.vendor_shared.28.arm64", sharedVariant).Output("libvendor_available.so")
+	// libvendor_available.so is installed by libvendor_available.vendor_shared.30.arm64
+	ctx.ModuleForTests("libvendor_available.vendor_shared.30.arm64", sharedVariant).Output("libvendor_available.so")
 
 	// libvendor_without_snapshot.so is installed by libvendor_without_snapshot
 	ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
 
-	// bin is installed by bin.vendor_binary.28.arm64
-	ctx.ModuleForTests("bin.vendor_binary.28.arm64", binaryVariant).Output("bin")
+	// bin is installed by bin.vendor_binary.30.arm64
+	ctx.ModuleForTests("bin.vendor_binary.30.arm64", binaryVariant).Output("bin")
 
-	// bin32 is installed by bin32.vendor_binary.28.arm64
-	ctx.ModuleForTests("bin32.vendor_binary.28.arm64", binary32Variant).Output("bin32")
+	// bin32 is installed by bin32.vendor_binary.30.arm64
+	ctx.ModuleForTests("bin32.vendor_binary.30.arm64", binary32Variant).Output("bin32")
 
 	// bin_without_snapshot is installed by bin_without_snapshot
 	ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
 
-	// libvendor, libvendor_available and bin don't have vendor.28 variant
+	// libvendor, libvendor_available and bin don't have vendor.30 variant
 	libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
 	if inList(sharedVariant, libvendorVariants) {
 		t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
@@ -819,6 +865,18 @@
 
 func TestVendorSnapshotSanitizer(t *testing.T) {
 	bp := `
+	vendor_snapshot {
+		name: "vendor_snapshot",
+		version: "28",
+		arch: {
+			arm64: {
+				static_libs: [
+					"libsnapshot",
+					"note_memtag_heap_sync",
+				],
+			},
+		},
+	}
 	vendor_snapshot_static {
 		name: "libsnapshot",
 		vendor: true,
@@ -833,8 +891,41 @@
 			},
 		},
 	}
+
+	vendor_snapshot_static {
+		name: "note_memtag_heap_sync",
+		vendor: true,
+		target_arch: "arm64",
+		version: "28",
+		arch: {
+			arm64: {
+				src: "note_memtag_heap_sync.a",
+			},
+		},
+	}
+
+	cc_test {
+		name: "vstest",
+		gtest: false,
+		vendor: true,
+		compile_multilib: "64",
+		nocrt: true,
+		no_libcrt: true,
+		stl: "none",
+		static_libs: ["libsnapshot"],
+		system_shared_libs: [],
+	}
 `
-	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
+
+	mockFS := map[string][]byte{
+		"vendor/Android.bp":              []byte(bp),
+		"vendor/libc++demangle.a":        nil,
+		"vendor/libsnapshot.a":           nil,
+		"vendor/libsnapshot.cfi.a":       nil,
+		"vendor/note_memtag_heap_sync.a": nil,
+	}
+
+	config := TestConfig(t.TempDir(), android.Android, nil, "", mockFS)
 	config.TestProductVariables.DeviceVndkVersion = StringPtr("28")
 	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
 	ctx := testCcWithConfig(t, config)
diff --git a/rust/config/global.go b/rust/config/global.go
index 9208ddb..18776ab 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
 var pctx = android.NewPackageContext("android/soong/rust/config")
 
 var (
-	RustDefaultVersion = "1.50.0"
+	RustDefaultVersion = "1.51.0"
 	RustDefaultBase    = "prebuilts/rust/"
 	DefaultEdition     = "2018"
 	Stdlibs            = []string{
diff --git a/rust/config/lints.go b/rust/config/lints.go
index 7c05e4f..ef6b315 100644
--- a/rust/config/lints.go
+++ b/rust/config/lints.go
@@ -54,6 +54,7 @@
 		"-A clippy::type-complexity",
 		"-A clippy::unnecessary-wraps",
 		"-A clippy::unusual-byte-groupings",
+		"-A clippy::upper-case-acronyms",
 	}
 
 	// Rust lints for vendor code.
diff --git a/rust/rust.go b/rust/rust.go
index 566ad37..34e197a 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -798,6 +798,11 @@
 	return ok && tag == dylibDepTag
 }
 
+func IsRlibDepTag(depTag blueprint.DependencyTag) bool {
+	tag, ok := depTag.(dependencyTag)
+	return ok && tag == rlibDepTag
+}
+
 type autoDep struct {
 	variation string
 	depTag    dependencyTag
diff --git a/rust/sanitize.go b/rust/sanitize.go
index 394f4c5..ae3eff0 100644
--- a/rust/sanitize.go
+++ b/rust/sanitize.go
@@ -44,7 +44,6 @@
 	"-C llvm-args=-sanitizer-coverage-level=3",
 	"-C llvm-args=-sanitizer-coverage-trace-compares",
 	"-C llvm-args=-sanitizer-coverage-inline-8bit-counters",
-	"-C llvm-args=-sanitizer-coverage-stack-depth",
 	"-C llvm-args=-sanitizer-coverage-trace-geps",
 	"-C llvm-args=-sanitizer-coverage-prune-blocks=0",
 	"-Z sanitizer=address",
diff --git a/scripts/strip.sh b/scripts/strip.sh
index 43e6cbf..e3e5273 100755
--- a/scripts/strip.sh
+++ b/scripts/strip.sh
@@ -18,7 +18,6 @@
 # Inputs:
 #  Environment:
 #   CLANG_BIN: path to the clang bin directory
-#   CROSS_COMPILE: prefix added to readelf, objcopy tools
 #   XZ: path to the xz binary
 #  Arguments:
 #   -i ${file}: input file (required)
@@ -69,7 +68,7 @@
 
     KEEP_SYMBOLS="--strip-unneeded-symbol=* --keep-symbols="
     KEEP_SYMBOLS+="${outfile}.symbolList"
-    "${CROSS_COMPILE}objcopy" -w "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
+    "${CLANG_BIN}/llvm-objcopy" -w "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
 }
 
 do_strip_keep_mini_debug_info() {
@@ -78,18 +77,13 @@
     "${CLANG_BIN}/llvm-strip" --strip-all --keep-section=.ARM.attributes --remove-section=.comment "${infile}" -o "${outfile}.tmp" || fail=true
 
     if [ -z $fail ]; then
-        # Current prebult llvm-objcopy does not support --only-keep-debug flag,
-        # and cannot process object files that are produced with the flag. Use
-        # GNU objcopy instead for now. (b/141010852)
-        "${CROSS_COMPILE}objcopy" --only-keep-debug "${infile}" "${outfile}.debug"
+        "${CLANG_BIN}/llvm-objcopy" --only-keep-debug "${infile}" "${outfile}.debug"
         "${CLANG_BIN}/llvm-nm" -D "${infile}" --format=posix --defined-only 2> /dev/null | awk '{ print $1 }' | sort >"${outfile}.dynsyms"
         "${CLANG_BIN}/llvm-nm" "${infile}" --format=posix --defined-only | awk '{ if ($2 == "T" || $2 == "t" || $2 == "D") print $1 }' | sort > "${outfile}.funcsyms"
         comm -13 "${outfile}.dynsyms" "${outfile}.funcsyms" > "${outfile}.keep_symbols"
         echo >> "${outfile}.keep_symbols" # Ensure that the keep_symbols file is not empty.
-        "${CROSS_COMPILE}objcopy" --rename-section .debug_frame=saved_debug_frame "${outfile}.debug" "${outfile}.mini_debuginfo"
-        "${CROSS_COMPILE}objcopy" -S --remove-section .gdb_index --remove-section .comment --remove-section .rustc --keep-symbols="${outfile}.keep_symbols" "${outfile}.mini_debuginfo"
-        "${CROSS_COMPILE}objcopy" --rename-section saved_debug_frame=.debug_frame "${outfile}.mini_debuginfo"
-        "${XZ}" --block-size=64k --threads=0 "${outfile}.mini_debuginfo"
+        "${CLANG_BIN}/llvm-objcopy" -S --keep-section .debug_frame --keep-symbols="${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo"
+        "${XZ}" --keep --block-size=64k --threads=0 "${outfile}.mini_debuginfo"
 
         "${CLANG_BIN}/llvm-objcopy" --add-section .gnu_debugdata="${outfile}.mini_debuginfo.xz" "${outfile}.tmp"
         rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
@@ -196,7 +190,6 @@
 cat <<EOF > "${depsfile}"
 ${outfile}: \
   ${infile} \
-  ${CROSS_COMPILE}objcopy \
   ${CLANG_BIN}/llvm-nm \
   ${CLANG_BIN}/llvm-objcopy \
   ${CLANG_BIN}/llvm-readelf \