Merge "Fix kernel build tools" into main
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index 43d5b57..2549f11 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -122,6 +122,7 @@
 build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
 
 build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
+build:linux_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86
 build:linux_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
 build:linux_bionic_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64
 build:linux_musl_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index d5c40eb..26baf89 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -2247,3 +2247,38 @@
     ]`,
 			})}})
 }
+
+func TestCcLibraryWithProtoInGeneratedSrcs(t *testing.T) {
+	runCcLibraryStaticTestCase(t, Bp2buildTestCase{
+		Description:                "cc_library with a .proto file generated from a genrule",
+		ModuleTypeUnderTest:        "cc_library_static",
+		ModuleTypeUnderTestFactory: cc.LibraryStaticFactory,
+		Blueprint: soongCcLibraryPreamble + `
+cc_library_static {
+	name: "mylib",
+	generated_sources: ["myprotogen"],
+}
+genrule {
+	name: "myprotogen",
+	out: ["myproto.proto"],
+}
+` + simpleModuleDoNotConvertBp2build("cc_library", "libprotobuf-cpp-lite"),
+		ExpectedBazelTargets: []string{
+			MakeBazelTarget("cc_library_static", "mylib", AttrNameToString{
+				"local_includes":                    `["."]`,
+				"deps":                              `[":libprotobuf-cpp-lite"]`,
+				"implementation_whole_archive_deps": `[":mylib_cc_proto_lite"]`,
+			}),
+			MakeBazelTarget("cc_lite_proto_library", "mylib_cc_proto_lite", AttrNameToString{
+				"deps": `[":mylib_proto"]`,
+			}),
+			MakeBazelTarget("proto_library", "mylib_proto", AttrNameToString{
+				"srcs": `[":myprotogen"]`,
+			}),
+			MakeBazelTargetNoRestrictions("genrule", "myprotogen", AttrNameToString{
+				"cmd":  `""`,
+				"outs": `["myproto.proto"]`,
+			}),
+		},
+	})
+}
diff --git a/cc/Android.bp b/cc/Android.bp
index e88ea03..c32d854 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -37,6 +37,7 @@
         "linkable.go",
         "lto.go",
         "makevars.go",
+        "orderfile.go",
         "pgo.go",
         "prebuilt.go",
         "proto.go",
@@ -104,6 +105,7 @@
         "lto_test.go",
         "ndk_test.go",
         "object_test.go",
+        "orderfile_test.go",
         "prebuilt_test.go",
         "proto_test.go",
         "sanitize_test.go",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 9e485d6..9d90a5b 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -48,6 +48,8 @@
 
 	genrulePartition = "genrule"
 
+	protoFromGenPartition = "proto_gen"
+
 	hdrPartition = "hdr"
 
 	stubsSuffix = "_stub_libs_current"
@@ -126,6 +128,41 @@
 	}
 }
 
+// Returns an unchanged label and a bool indicating whether the dep is a genrule that produces .proto files
+func protoFromGenPartitionMapper(pathCtx android.BazelConversionContext) bazel.LabelMapper {
+	return func(ctx bazel.OtherModuleContext, label bazel.Label) (string, bool) {
+		mod, exists := ctx.ModuleFromName(label.OriginalModuleName)
+		if !exists {
+			return label.Label, false
+		}
+		gen, isGen := mod.(*genrule.Module)
+		if !isGen {
+			return label.Label, false
+		}
+		if containsProto(ctx, gen.RawOutputFiles(pathCtx)) {
+			// Return unmodified label + true
+			// True will ensure that this module gets dropped from `srcs` of the generated cc_* target. `srcs` is reserved for .cpp files
+			return label.Label, true
+		}
+		return label.Label, false
+	}
+}
+
+// Returns true if srcs contains only .proto files
+// Raises an exception if there is a combination of .proto and non .proto srcs
+func containsProto(ctx bazel.OtherModuleContext, srcs []string) bool {
+	onlyProtos := false
+	for _, src := range srcs {
+		if strings.HasSuffix(src, ".proto") {
+			onlyProtos = true
+		} else if onlyProtos {
+			// This is not a proto file, and we have encountered a .proto file previously
+			ctx.ModuleErrorf("TOOD: Add bp2build support combination of .proto and non .proto files in outs of genrule")
+		}
+	}
+	return onlyProtos
+}
+
 // groupSrcsByExtension partitions `srcs` into groups based on file extension.
 func groupSrcsByExtension(ctx android.BazelConversionPathContext, srcs bazel.LabelListAttribute) bazel.PartitionToLabelListAttribute {
 	// Convert filegroup dependencies into extension-specific filegroups filtered in the filegroup.bzl
@@ -159,10 +196,11 @@
 		// 		contains .l or .ll files we will need to find a way to add a
 		// 		LabelMapper for these that identifies these filegroups and
 		//		converts them appropriately
-		lSrcPartition:       bazel.LabelPartition{Extensions: []string{".l"}},
-		llSrcPartition:      bazel.LabelPartition{Extensions: []string{".ll"}},
-		rScriptSrcPartition: bazel.LabelPartition{Extensions: []string{".fs", ".rscript"}},
-		xsdSrcPartition:     bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
+		lSrcPartition:         bazel.LabelPartition{Extensions: []string{".l"}},
+		llSrcPartition:        bazel.LabelPartition{Extensions: []string{".ll"}},
+		rScriptSrcPartition:   bazel.LabelPartition{Extensions: []string{".fs", ".rscript"}},
+		xsdSrcPartition:       bazel.LabelPartition{LabelMapper: android.XsdLabelMapper(xsdConfigCppTarget)},
+		protoFromGenPartition: bazel.LabelPartition{LabelMapper: protoFromGenPartitionMapper(ctx)},
 		// C++ is the "catch-all" group, and comprises generated sources because we don't
 		// know the language of these sources until the genrule is executed.
 		cppSrcPartition:     bazel.LabelPartition{Extensions: []string{".cpp", ".cc", ".cxx", ".mm"}, LabelMapper: addSuffixForFilegroup("_cpp_srcs"), Keep_remainder: true},
@@ -594,6 +632,7 @@
 	partitionedHdrs := partitionHeaders(ctx, exportHdrs)
 
 	ca.protoSrcs = partitionedSrcs[protoSrcPartition]
+	ca.protoSrcs.Append(partitionedSrcs[protoFromGenPartition])
 	ca.aidlSrcs = partitionedSrcs[aidlSrcPartition]
 
 	for p, lla := range partitionedSrcs {
diff --git a/cc/cc.go b/cc/cc.go
index be67286..3b92696 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -74,6 +74,9 @@
 		ctx.TopDown("afdo_deps", afdoDepsMutator)
 		ctx.BottomUp("afdo", afdoMutator).Parallel()
 
+		ctx.TopDown("orderfile_deps", orderfileDepsMutator)
+		ctx.BottomUp("orderfile", orderfileMutator).Parallel()
+
 		ctx.TopDown("lto_deps", ltoDepsMutator)
 		ctx.BottomUp("lto", ltoMutator).Parallel()
 
@@ -526,6 +529,7 @@
 	getVndkExtendsModuleName() string
 	isAfdoCompile() bool
 	isPgoCompile() bool
+	isOrderfileCompile() bool
 	isCfi() bool
 	isFuzzer() bool
 	isNDKStubLibrary() bool
@@ -885,6 +889,7 @@
 	lto      *lto
 	afdo     *afdo
 	pgo      *pgo
+	orderfile *orderfile
 
 	library libraryInterface
 
@@ -1259,6 +1264,9 @@
 	if c.pgo != nil {
 		c.AddProperties(c.pgo.props()...)
 	}
+	if c.orderfile != nil {
+		c.AddProperties(c.orderfile.props()...)
+	}
 	for _, feature := range c.features {
 		c.AddProperties(feature.props()...)
 	}
@@ -1392,6 +1400,13 @@
 	return false
 }
 
+func (c *Module) isOrderfileCompile() bool {
+	if orderfile := c.orderfile; orderfile != nil {
+		return orderfile.Properties.OrderfileLoad
+	}
+	return false
+}
+
 func (c *Module) isCfi() bool {
 	if sanitize := c.sanitize; sanitize != nil {
 		return Bool(sanitize.Properties.SanitizeMutated.Cfi)
@@ -1697,6 +1712,10 @@
 	return ctx.mod.isPgoCompile()
 }
 
+func (ctx *moduleContextImpl) isOrderfileCompile() bool {
+	return ctx.mod.isOrderfileCompile()
+}
+
 func (ctx *moduleContextImpl) isCfi() bool {
 	return ctx.mod.isCfi()
 }
@@ -1806,6 +1825,7 @@
 	module.lto = &lto{}
 	module.afdo = &afdo{}
 	module.pgo = &pgo{}
+	module.orderfile = &orderfile{}
 	return module
 }
 
@@ -2234,6 +2254,9 @@
 	if c.pgo != nil {
 		flags = c.pgo.flags(ctx, flags)
 	}
+	if c.orderfile != nil {
+		flags = c.orderfile.flags(ctx, flags)
+	}
 	for _, feature := range c.features {
 		flags = feature.flags(ctx, flags)
 	}
@@ -2376,6 +2399,9 @@
 	if c.lto != nil {
 		c.lto.begin(ctx)
 	}
+	if c.orderfile != nil {
+		c.orderfile.begin(ctx)
+	}
 	if c.pgo != nil {
 		c.pgo.begin(ctx)
 	}
@@ -4284,6 +4310,7 @@
 		&LTOProperties{},
 		&AfdoProperties{},
 		&PgoProperties{},
+		&OrderfileProperties{},
 		&android.ProtoProperties{},
 		// RustBindgenProperties is included here so that cc_defaults can be used for rust_bindgen modules.
 		&RustBindgenClangProperties{},
diff --git a/cc/orderfile.go b/cc/orderfile.go
new file mode 100644
index 0000000..cc1ab29
--- /dev/null
+++ b/cc/orderfile.go
@@ -0,0 +1,257 @@
+// Copyright 2023 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.
+//
+// Note: If you want to know how to use orderfile for your binary or shared
+// library, you can go look at the README in toolchains/pgo-profiles/orderfiles
+
+package cc
+
+import (
+	"fmt"
+
+	"android/soong/android"
+)
+
+// Order files are text files containing symbols representing functions names.
+// Linkers (lld) uses order files to layout functions in a specific order.
+// These binaries with ordered symbols will reduce page faults and improve a program's launch time
+// due to the efficient loading of symbols during a program’s cold-start.
+var (
+	// Add flags to ignore warnings about symbols not be found
+	// or not allowed to be ordered
+	orderfileOtherFlags = []string{
+		"-Wl,--no-warn-symbol-ordering",
+	}
+
+	// Add folder projects for orderfiles
+	globalOrderfileProjects = []string{
+		"toolchain/pgo-profiles/orderfiles",
+		"vendor/google_data/pgo_profile/orderfiles",
+	}
+)
+
+var orderfileProjectsConfigKey = android.NewOnceKey("OrderfileProjects")
+
+const orderfileProfileFlag = "-forder-file-instrumentation"
+const orderfileUseFormat = "-Wl,--symbol-ordering-file=%s"
+
+func getOrderfileProjects(config android.DeviceConfig) []string {
+	return config.OnceStringSlice(orderfileProjectsConfigKey, func() []string {
+		return globalOrderfileProjects
+	})
+}
+
+func recordMissingOrderfile(ctx BaseModuleContext, missing string) {
+	getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true)
+}
+
+type OrderfileProperties struct {
+	Orderfile struct {
+		Instrumentation    *bool
+		Order_file_path    *string `android:"arch_variant"`
+		Load_order_file    *bool `android:"arch_variant"`
+		// Additional compiler flags to use when building this module
+		// for orderfile profiling.
+		Cflags []string `android:"arch_variant"`
+	} `android:"arch_variant"`
+
+	ShouldProfileModule 	  bool `blueprint:"mutated"`
+	OrderfileLoad             bool `blueprint:"mutated"`
+	OrderfileInstrLink        bool `blueprint:"mutated"`
+}
+
+type orderfile struct {
+	Properties OrderfileProperties
+}
+
+func (props *OrderfileProperties) shouldInstrument() bool {
+	return Bool(props.Orderfile.Instrumentation)
+}
+
+// ShouldLoadOrderfile returns true if we need to load the order file rather than
+// profile the binary or shared library
+func (props *OrderfileProperties) shouldLoadOrderfile() bool {
+	return Bool(props.Orderfile.Load_order_file) && props.Orderfile.Order_file_path != nil
+}
+
+// orderfileEnabled returns true for binaries and shared libraries
+// if instrument flag is set to true
+func (orderfile *orderfile) orderfileEnabled() bool {
+	return orderfile != nil && orderfile.Properties.shouldInstrument()
+}
+
+// orderfileLinkEnabled returns true for binaries and shared libraries
+// if you should instrument dependencies
+func (orderfile *orderfile) orderfileLinkEnabled() bool {
+	return orderfile != nil && orderfile.Properties.OrderfileInstrLink
+}
+
+func (orderfile *orderfile) props() []interface{} {
+	return []interface{}{&orderfile.Properties}
+}
+
+// Get the path to the order file by checking it is valid and not empty
+func (props *OrderfileProperties) getOrderfile(ctx BaseModuleContext) android.OptionalPath {
+	orderFile := *props.Orderfile.Order_file_path
+
+	// Test if the order file is present in any of the Orderfile projects
+	for _, profileProject := range getOrderfileProjects(ctx.DeviceConfig()) {
+		path := android.ExistentPathForSource(ctx, profileProject, orderFile)
+		if path.Valid() {
+			return path
+		}
+	}
+
+	// Record that this module's order file is absent
+	missing := *props.Orderfile.Order_file_path + ":" + ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
+	recordMissingOrderfile(ctx, missing)
+
+	return android.OptionalPath{}
+}
+
+func (props *OrderfileProperties) addInstrumentationProfileGatherFlags(ctx ModuleContext, flags Flags) Flags {
+	flags.Local.CFlags = append(flags.Local.CFlags, props.Orderfile.Cflags...)
+	flags.Local.CFlags = append(flags.Local.CFlags, orderfileProfileFlag)
+	flags.Local.CFlags = append(flags.Local.CFlags, "-mllvm -enable-order-file-instrumentation")
+	flags.Local.LdFlags = append(flags.Local.LdFlags, orderfileProfileFlag)
+	return flags
+}
+
+
+func (props *OrderfileProperties) loadOrderfileFlags(ctx ModuleContext, file string) []string {
+	flags := []string{fmt.Sprintf(orderfileUseFormat, file)}
+	flags = append(flags, orderfileOtherFlags...)
+	return flags
+}
+
+func (props *OrderfileProperties) addLoadFlags(ctx ModuleContext, flags Flags) Flags {
+	orderFile := props.getOrderfile(ctx)
+	orderFilePath := orderFile.Path()
+	loadFlags := props.loadOrderfileFlags(ctx, orderFilePath.String())
+
+	flags.Local.CFlags = append(flags.Local.CFlags, loadFlags...)
+	flags.Local.LdFlags = append(flags.Local.LdFlags, loadFlags...)
+
+	// Update CFlagsDeps and LdFlagsDeps so the module is rebuilt
+	// if orderfile gets updated
+	flags.CFlagsDeps = append(flags.CFlagsDeps, orderFilePath)
+	flags.LdFlagsDeps = append(flags.LdFlagsDeps, orderFilePath)
+	return flags
+}
+
+func (orderfile *orderfile) begin(ctx BaseModuleContext) {
+	// Currently, we are not enabling orderfiles for host
+	if ctx.Host() {
+		return
+	}
+
+	// Currently, we are not enabling orderfiles to begin from static libraries
+	if ctx.static() && !ctx.staticBinary() {
+		return
+	}
+
+	if ctx.DeviceConfig().ClangCoverageEnabled() {
+		return
+	}
+
+	// Checking if orderfile is enabled for this module
+	if !orderfile.orderfileEnabled() {
+		return
+	}
+
+	orderfile.Properties.OrderfileLoad = orderfile.Properties.shouldLoadOrderfile()
+	orderfile.Properties.ShouldProfileModule = !orderfile.Properties.shouldLoadOrderfile()
+	orderfile.Properties.OrderfileInstrLink = orderfile.orderfileEnabled() && !orderfile.Properties.shouldLoadOrderfile()
+}
+
+func (orderfile *orderfile) flags(ctx ModuleContext, flags Flags) Flags {
+	props := orderfile.Properties
+	// Add flags to load the orderfile using the path in its Android.bp
+	if orderfile.Properties.OrderfileLoad {
+		flags = props.addLoadFlags(ctx, flags)
+		return flags
+	}
+
+	// Add flags to profile this module
+	if props.ShouldProfileModule {
+		flags = props.addInstrumentationProfileGatherFlags(ctx, flags)
+		return flags
+	}
+
+	return flags
+}
+
+// Propagate profile orderfile flags down from binaries and shared libraries
+// We do not allow propagation for load flags because the orderfile is specific
+// to the module (binary / shared library)
+func orderfileDepsMutator(mctx android.TopDownMutatorContext) {
+	if m, ok := mctx.Module().(*Module); ok {
+		if !m.orderfile.orderfileLinkEnabled() {
+			return
+		}
+		mctx.WalkDeps(func(dep android.
+			Module, parent android.Module) bool {
+			tag := mctx.OtherModuleDependencyTag(dep)
+			libTag, isLibTag := tag.(libraryDependencyTag)
+
+			// Do not recurse down non-static dependencies
+			if isLibTag {
+				if !libTag.static() {
+					return false
+				}
+			} else {
+				if tag != objDepTag && tag != reuseObjTag {
+					return false
+				}
+			}
+
+			if dep, ok := dep.(*Module); ok {
+				if m.orderfile.Properties.OrderfileInstrLink {
+					dep.orderfile.Properties.OrderfileInstrLink = true;
+				}
+			}
+
+			return true
+		})
+	}
+}
+
+// Create orderfile variants for modules that need them
+func orderfileMutator(mctx android.BottomUpMutatorContext) {
+	if m, ok := mctx.Module().(*Module); ok && m.orderfile != nil {
+		if !m.static() && m.orderfile.orderfileEnabled() {
+			mctx.SetDependencyVariation("orderfile")
+			return
+		}
+
+		variationNames := []string{""}
+		if m.orderfile.Properties.OrderfileInstrLink {
+			variationNames = append(variationNames, "orderfile")
+		}
+
+		if len(variationNames) > 1 {
+			modules := mctx.CreateVariations(variationNames...)
+			for i, name := range variationNames {
+				if name == "" {
+					continue
+				}
+				variation := modules[i].(*Module)
+				variation.Properties.PreventInstall = true
+				variation.Properties.HideFromMake = true
+				variation.orderfile.Properties.ShouldProfileModule = true
+				variation.orderfile.Properties.OrderfileLoad = false
+			}
+		}
+	}
+}
diff --git a/cc/orderfile_test.go b/cc/orderfile_test.go
new file mode 100644
index 0000000..9e30bd2
--- /dev/null
+++ b/cc/orderfile_test.go
@@ -0,0 +1,493 @@
+// Copyright 2023 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 cc
+
+import (
+	"testing"
+	"strings"
+
+	"android/soong/android"
+)
+
+func TestOrderfileProfileSharedLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := libTest.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileLoadSharedLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "libTest.orderfile",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/libTest.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/libTest.orderfile"
+
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := libTest.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileProfileBinary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_binary {
+		name: "test",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	test := result.ModuleForTests("test", "android_arm64_armv8-a")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := test.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := test.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to enable orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+func TestOrderfileLoadBinary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_binary {
+		name: "test",
+		srcs: ["test.c"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "test.orderfile",
+		},
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
+
+	test := result.ModuleForTests("test", "android_arm64_armv8-a")
+
+	// Check cFlags of orderfile-enabled module
+	cFlags := test.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check ldFlags of orderfile-enabled module
+	ldFlags := test.Rule("ld").Args["ldFlags"]
+	if !strings.Contains(ldFlags, expectedCFlag) {
+		t.Errorf("Expected 'test' to load orderfile, but did not find %q in ldflags %q", expectedCFlag, ldFlags)
+	}
+}
+
+// Profile flags should propagate through static libraries
+func TestOrderfileProfilePropagateStaticDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of orderfile variant static libraries
+	libFooOfVariant  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static_orderfile")
+	libBarOfVariant  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static_orderfile")
+
+	cFlags = libFooOfVariant.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFooOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBarOfVariant.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBarOfVariant' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFooOfVariant.Module()) {
+		t.Errorf("libTest missing dependency on orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFooOfVariant.Module(), libBarOfVariant.Module()) {
+		t.Errorf("libTest missing dependency on orderfile variant of libBar")
+	}
+
+	// Check cFlags of the non-orderfile variant static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check no dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest has dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest has dependency on non-orderfile variant of libBar")
+	}
+}
+
+// Load flags should never propagate
+func TestOrderfileLoadPropagateStaticDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: true,
+			order_file_path: "test.orderfile",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+		android.FixtureAddTextFile("toolchain/pgo-profiles/orderfiles/test.orderfile", "TEST"),
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-Wl,--symbol-ordering-file=toolchain/pgo-profiles/orderfiles/test.orderfile"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to load orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the non-orderfile variant static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' not load orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for static libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
+
+// Profile flags should not propagate through shared libraries
+func TestOrderfileProfilePropagateSharedDeps(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_shared {
+		name: "libTest",
+		srcs: ["test.c"],
+		shared_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_shared {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of orderfile-enabled module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_shared")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if !strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to enable orderfile, but did not find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the static and shared libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_shared")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant static libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
+
+// Profile flags should not work or be propagated if orderfile flags start at a static library
+func TestOrderfileProfileStaticLibrary(t *testing.T) {
+	t.Parallel()
+	bp := `
+	cc_library_static {
+		name: "libTest",
+		srcs: ["test.c"],
+		static_libs: ["libFoo"],
+		orderfile : {
+			instrumentation: true,
+			load_order_file: false,
+			order_file_path: "",
+		},
+	}
+
+	cc_library_static {
+		name: "libFoo",
+		srcs: ["foo.c"],
+		static_libs: ["libBar"],
+	}
+
+	cc_library_static {
+		name: "libBar",
+		srcs: ["bar.c"],
+	}
+	`
+
+	result := android.GroupFixturePreparers(
+		prepareForCcTest,
+	).RunTestWithBp(t, bp)
+
+	expectedCFlag := "-forder-file-instrumentation"
+
+	// Check cFlags of module
+	libTest := result.ModuleForTests("libTest", "android_arm64_armv8-a_static")
+
+	cFlags := libTest.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libTest' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check cFlags of the static libraries
+	libFoo  := result.ModuleForTests("libFoo", "android_arm64_armv8-a_static")
+	libBar  := result.ModuleForTests("libBar", "android_arm64_armv8-a_static")
+
+	cFlags = libFoo.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libFoo' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	cFlags = libBar.Rule("cc").Args["cFlags"]
+	if strings.Contains(cFlags, expectedCFlag) {
+		t.Errorf("Expected 'libBar' to not enable orderfile, but did find %q in cflags %q", expectedCFlag, cFlags)
+	}
+
+	// Check dependency edge from orderfile-enabled module to non-orderfile variant libraries
+	if !hasDirectDep(result, libTest.Module(), libFoo.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libFoo")
+	}
+
+	if !hasDirectDep(result, libFoo.Module(), libBar.Module()) {
+		t.Errorf("libTest missing dependency on non-orderfile variant of libBar")
+	}
+
+	// Make sure no orderfile variants are created for static libraries because the flags were not propagated
+	libFooVariants := result.ModuleVariantsForTests("libFoo")
+	for _, v := range libFooVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libFoo' to not contain 'orderfile', but found %q", v)
+		}
+	}
+
+	libBarVariants := result.ModuleVariantsForTests("libBar")
+	for _, v := range libBarVariants {
+		if strings.Contains(v, "orderfile") {
+			t.Errorf("Expected variants for 'libBar' to not contain 'orderfile', but found %q", v)
+		}
+	}
+}
\ No newline at end of file
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 6806e63..30bce9b 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -87,6 +87,8 @@
 
 	hostOnlySanitizeFlags   = []string{"-fno-sanitize-recover=all"}
 	deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all", "-ftrap-function=abort"}
+
+	noSanitizeLinkRuntimeFlag = "-fno-sanitize-link-runtime"
 )
 
 type SanitizerType int
@@ -424,6 +426,8 @@
 	exportedVars.ExportString("CfiExportsMapFilename", cfiExportsMapFilename)
 	exportedVars.ExportString("CfiAssemblySupportFlag", cfiAssemblySupportFlag)
 
+	exportedVars.ExportString("NoSanitizeLinkRuntimeFlag", noSanitizeLinkRuntimeFlag)
+
 	android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider)
 	android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider)
 }
@@ -925,7 +929,7 @@
 			// Bionic and musl sanitizer runtimes have already been added as dependencies so that
 			// the right variant of the runtime will be used (with the "-android" or "-musl"
 			// suffixes), so don't let clang the runtime library.
-			flags.Local.LdFlags = append(flags.Local.LdFlags, "-fno-sanitize-link-runtime")
+			flags.Local.LdFlags = append(flags.Local.LdFlags, noSanitizeLinkRuntimeFlag)
 		} else {
 			// Host sanitizers only link symbols in the final executable, so
 			// there will always be undefined symbols in intermediate libraries.
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 69ba1e9..8a8d605 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -1012,16 +1012,7 @@
 			Tags: tags,
 		}, attrs)
 	} else {
-		// The Out prop is not in an immediately accessible field
-		// in the Module struct, so use GetProperties and cast it
-		// to the known struct prop.
-		var outs []string
-		for _, propIntf := range m.GetProperties() {
-			if props, ok := propIntf.(*genRuleProperties); ok {
-				outs = props.Out
-				break
-			}
-		}
+		outs := m.RawOutputFiles(ctx)
 		for _, out := range outs {
 			if out == bazelName {
 				// This is a workaround to circumvent a Bazel warning where a genrule's
@@ -1096,6 +1087,25 @@
 	Export_includes []string
 }
 
+// RawOutputFfiles returns the raw outputs specified in Android.bp
+// This does not contain the fully resolved path relative to the top of the tree
+func (g *Module) RawOutputFiles(ctx android.BazelConversionContext) []string {
+	if ctx.Config().BuildMode != android.Bp2build {
+		ctx.ModuleErrorf("RawOutputFiles is only supported in bp2build mode")
+	}
+	// The Out prop is not in an immediately accessible field
+	// in the Module struct, so use GetProperties and cast it
+	// to the known struct prop.
+	var outs []string
+	for _, propIntf := range g.GetProperties() {
+		if props, ok := propIntf.(*genRuleProperties); ok {
+			outs = props.Out
+			break
+		}
+	}
+	return outs
+}
+
 var Bool = proptools.Bool
 var String = proptools.String
 
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 1bb4996..8494d02 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -122,3 +122,17 @@
 --warning_check RemoteViewLayout
 --warning_check SupportAnnotationUsage
 --warning_check UniqueConstants
+
+# TODO(b/294098365): these checks fail in AOSP, but pass downstream
+--warning_check ForegroundServiceType
+--warning_check MutableImplicitPendingIntent
+
+--warning_check ExactAlarm
+--warning_check ExpiredTargetSdkVersion
+--warning_check ForegroundServicePermission
+--warning_check ObsoleteSdkInt
+--warning_check ScheduleExactAlarm
+--warning_check StartActivityAndCollapseDeprecated
+--warning_check UnspecifiedRegisterReceiverFlag
+--warning_check WearMaterialTheme
+--warning_check WearStandaloneAppFlag