Merge "Rename ApexCqueryInfo to ApexInfo"
diff --git a/android/bazel_test.go b/android/bazel_test.go
index 3164b23..7b38b6a 100644
--- a/android/bazel_test.go
+++ b/android/bazel_test.go
@@ -423,3 +423,21 @@
 		}
 	}
 }
+
+func TestShouldKeepExistingBuildFileForDir(t *testing.T) {
+	allowlist := NewBp2BuildAllowlist()
+	// entry "a/b2/c2" is moot because of its parent "a/b2"
+	allowlist.SetKeepExistingBuildFile(map[string]bool{"a": false, "a/b1": false, "a/b2": true, "a/b1/c1": true, "a/b2/c2": false})
+	truths := []string{"a", "a/b1", "a/b2", "a/b1/c1", "a/b2/c", "a/b2/c2", "a/b2/c2/d"}
+	falsities := []string{"a1", "a/b", "a/b1/c"}
+	for _, dir := range truths {
+		if !allowlist.ShouldKeepExistingBuildFileForDir(dir) {
+			t.Errorf("%s expected TRUE but was FALSE", dir)
+		}
+	}
+	for _, dir := range falsities {
+		if allowlist.ShouldKeepExistingBuildFileForDir(dir) {
+			t.Errorf("%s expected FALSE but was TRUE", dir)
+		}
+	}
+}
diff --git a/android/config.go b/android/config.go
index df2c767..50f63ea 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1109,7 +1109,7 @@
 	return c.config.productVariables.WithDexpreopt
 }
 
-func (c *config) FrameworksBaseDirExists(ctx PathContext) bool {
+func (c *config) FrameworksBaseDirExists(ctx PathGlobContext) bool {
 	return ExistentPathForSource(ctx, "frameworks", "base", "Android.bp").Valid()
 }
 
diff --git a/android/licenses.go b/android/licenses.go
index c47b3e6..c6b3243 100644
--- a/android/licenses.go
+++ b/android/licenses.go
@@ -340,4 +340,5 @@
 	ctx.Strict("COMPLIANCENOTICE_SHIPPEDLIBS", ctx.Config().HostToolPath(ctx, "compliancenotice_shippedlibs").String())
 	ctx.Strict("COMPLIANCE_LISTSHARE", ctx.Config().HostToolPath(ctx, "compliance_listshare").String())
 	ctx.Strict("COMPLIANCE_CHECKSHARE", ctx.Config().HostToolPath(ctx, "compliance_checkshare").String())
+	ctx.Strict("COMPLIANCE_SBOM", ctx.Config().HostToolPath(ctx, "compliance_sbom").String())
 }
diff --git a/android/ninja_deps_test.go b/android/ninja_deps_test.go
index 947c257..d6afcc0 100644
--- a/android/ninja_deps_test.go
+++ b/android/ninja_deps_test.go
@@ -18,21 +18,6 @@
 	"testing"
 )
 
-func init() {
-	// This variable uses ExistentPathForSource on a PackageVarContext, which is a PathContext
-	// that is not a PathGlobContext.  That requires the deps to be stored in the Config.
-	pctx.VariableFunc("test_ninja_deps_variable", func(ctx PackageVarContext) string {
-		// Using ExistentPathForSource to look for a file that does not exist in a directory that
-		// does exist (test_ninja_deps) from a PackageVarContext adds a dependency from build.ninja
-		// to the directory.
-		if ExistentPathForSource(ctx, "test_ninja_deps/does_not_exist").Valid() {
-			return "true"
-		} else {
-			return "false"
-		}
-	})
-}
-
 func testNinjaDepsSingletonFactory() Singleton {
 	return testNinjaDepsSingleton{}
 }
@@ -40,33 +25,19 @@
 type testNinjaDepsSingleton struct{}
 
 func (testNinjaDepsSingleton) GenerateBuildActions(ctx SingletonContext) {
-	// Reference the test_ninja_deps_variable in a build statement so Blueprint is forced to
-	// evaluate it.
-	ctx.Build(pctx, BuildParams{
-		Rule:   Cp,
-		Input:  PathForTesting("foo"),
-		Output: PathForOutput(ctx, "test_ninja_deps_out"),
-		Args: map[string]string{
-			"cpFlags": "${test_ninja_deps_variable}",
-		},
-	})
+	ctx.Config().addNinjaFileDeps("foo")
 }
 
 func TestNinjaDeps(t *testing.T) {
-	fs := MockFS{
-		"test_ninja_deps/exists": nil,
-	}
-
 	result := GroupFixturePreparers(
 		FixtureRegisterWithContext(func(ctx RegistrationContext) {
 			ctx.RegisterSingletonType("test_ninja_deps_singleton", testNinjaDepsSingletonFactory)
 			ctx.RegisterSingletonType("ninja_deps_singleton", ninjaDepsSingletonFactory)
 		}),
-		fs.AddToFixture(),
 	).RunTest(t)
 
 	// Verify that the ninja file has a dependency on the test_ninja_deps directory.
-	if g, w := result.NinjaDeps, "test_ninja_deps"; !InList(w, g) {
+	if g, w := result.NinjaDeps, "foo"; !InList(w, g) {
 		t.Errorf("expected %q in %q", w, g)
 	}
 }
diff --git a/android/package_ctx.go b/android/package_ctx.go
index f354db8..c348c82 100644
--- a/android/package_ctx.go
+++ b/android/package_ctx.go
@@ -48,7 +48,7 @@
 
 var _ PathContext = &configErrorWrapper{}
 var _ errorfContext = &configErrorWrapper{}
-var _ PackageVarContext = &configErrorWrapper{}
+var _ PackageVarContext = &variableFuncContextWrapper{}
 var _ PackagePoolContext = &configErrorWrapper{}
 var _ PackageRuleContext = &configErrorWrapper{}
 
@@ -62,21 +62,33 @@
 	e.config.addNinjaFileDeps(deps...)
 }
 
-type PackageVarContext interface {
+type variableFuncContextWrapper struct {
+	configErrorWrapper
+	blueprint.VariableFuncContext
+}
+
+type PackagePoolContext interface {
 	PathContext
 	errorfContext
 }
 
-type PackagePoolContext PackageVarContext
-type PackageRuleContext PackageVarContext
+type PackageRuleContext PackagePoolContext
+
+type PackageVarContext interface {
+	PackagePoolContext
+	PathGlobContext
+}
 
 // VariableFunc wraps blueprint.PackageContext.VariableFunc, converting the interface{} config
 // argument to a PackageVarContext.
 func (p PackageContext) VariableFunc(name string,
 	f func(PackageVarContext) string) blueprint.Variable {
 
-	return p.PackageContext.VariableFunc(name, func(config interface{}) (string, error) {
-		ctx := &configErrorWrapper{p, config.(Config), nil}
+	return p.PackageContext.VariableFunc(name, func(bpctx blueprint.VariableFuncContext, config interface{}) (string, error) {
+		ctx := &variableFuncContextWrapper{
+			configErrorWrapper:  configErrorWrapper{p, config.(Config), nil},
+			VariableFuncContext: bpctx,
+		}
 		ret := f(ctx)
 		if len(ctx.errors) > 0 {
 			return "", ctx.errors[0]
diff --git a/android/paths.go b/android/paths.go
index 375297f..a6a54fa 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -39,6 +39,7 @@
 }
 
 type PathGlobContext interface {
+	PathContext
 	GlobWithDeps(globPattern string, excludes []string) ([]string, error)
 }
 
@@ -56,7 +57,6 @@
 // EarlyModulePathContext is a subset of EarlyModuleContext methods required by the
 // Path methods. These path methods can be called before any mutators have run.
 type EarlyModulePathContext interface {
-	PathContext
 	PathGlobContext
 
 	ModuleDir() string
@@ -375,7 +375,7 @@
 // ExistentPathsForSources returns a list of Paths rooted from SrcDir, *not* rooted from the
 // module's local source directory, that are found in the tree. If any are not found, they are
 // omitted from the list, and dependencies are added so that we're re-run when they are added.
-func ExistentPathsForSources(ctx PathContext, paths []string) Paths {
+func ExistentPathsForSources(ctx PathGlobContext, paths []string) Paths {
 	ret := make(Paths, 0, len(paths))
 	for _, path := range paths {
 		p := ExistentPathForSource(ctx, path)
@@ -1087,21 +1087,12 @@
 
 // existsWithDependencies returns true if the path exists, and adds appropriate dependencies to rerun if the
 // path does not exist.
-func existsWithDependencies(ctx PathContext, path SourcePath) (exists bool, err error) {
+func existsWithDependencies(ctx PathGlobContext, path SourcePath) (exists bool, err error) {
 	var files []string
 
-	if gctx, ok := ctx.(PathGlobContext); ok {
-		// Use glob to produce proper dependencies, even though we only want
-		// a single file.
-		files, err = gctx.GlobWithDeps(path.String(), nil)
-	} else {
-		var result pathtools.GlobResult
-		// We cannot add build statements in this context, so we fall back to
-		// AddNinjaFileDeps
-		result, err = ctx.Config().fs.Glob(path.String(), nil, pathtools.FollowSymlinks)
-		ctx.AddNinjaFileDeps(result.Deps...)
-		files = result.Matches
-	}
+	// Use glob to produce proper dependencies, even though we only want
+	// a single file.
+	files, err = ctx.GlobWithDeps(path.String(), nil)
 
 	if err != nil {
 		return false, fmt.Errorf("glob: %s", err.Error())
@@ -1124,7 +1115,7 @@
 	}
 
 	if modCtx, ok := ctx.(ModuleMissingDepsPathContext); ok && ctx.Config().AllowMissingDependencies() {
-		exists, err := existsWithDependencies(ctx, path)
+		exists, err := existsWithDependencies(modCtx, path)
 		if err != nil {
 			reportPathError(ctx, err)
 		}
@@ -1158,7 +1149,7 @@
 // rooted from the module's local source directory, if the path exists, or an empty OptionalPath if
 // it doesn't exist. Dependencies are added so that the ninja file will be regenerated if the state
 // of the path changes.
-func ExistentPathForSource(ctx PathContext, pathComponents ...string) OptionalPath {
+func ExistentPathForSource(ctx PathGlobContext, pathComponents ...string) OptionalPath {
 	path, err := pathForSource(ctx, pathComponents...)
 	if err != nil {
 		reportPathError(ctx, err)
diff --git a/apex/apex.go b/apex/apex.go
index b039d0d..a3872d3 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -225,7 +225,7 @@
 	// List of JNI libraries that are embedded inside this APEX.
 	Jni_libs []string
 
-	// List of rust dyn libraries
+	// List of rust dyn libraries that are embedded inside this APEX.
 	Rust_dyn_libs []string
 
 	// List of native executables that are embedded inside this APEX.
@@ -236,6 +236,41 @@
 
 	// List of filesystem images that are embedded inside this APEX bundle.
 	Filesystems []string
+
+	// List of native libraries to exclude from this APEX.
+	Exclude_native_shared_libs []string
+
+	// List of JNI libraries to exclude from this APEX.
+	Exclude_jni_libs []string
+
+	// List of rust dyn libraries to exclude from this APEX.
+	Exclude_rust_dyn_libs []string
+
+	// List of native executables to exclude from this APEX.
+	Exclude_binaries []string
+
+	// List of native tests to exclude from this APEX.
+	Exclude_tests []string
+
+	// List of filesystem images to exclude from this APEX bundle.
+	Exclude_filesystems []string
+}
+
+// Merge combines another ApexNativeDependencies into this one
+func (a *ApexNativeDependencies) Merge(b ApexNativeDependencies) {
+	a.Native_shared_libs = append(a.Native_shared_libs, b.Native_shared_libs...)
+	a.Jni_libs = append(a.Jni_libs, b.Jni_libs...)
+	a.Rust_dyn_libs = append(a.Rust_dyn_libs, b.Rust_dyn_libs...)
+	a.Binaries = append(a.Binaries, b.Binaries...)
+	a.Tests = append(a.Tests, b.Tests...)
+	a.Filesystems = append(a.Filesystems, b.Filesystems...)
+
+	a.Exclude_native_shared_libs = append(a.Exclude_native_shared_libs, b.Exclude_native_shared_libs...)
+	a.Exclude_jni_libs = append(a.Exclude_jni_libs, b.Exclude_jni_libs...)
+	a.Exclude_rust_dyn_libs = append(a.Exclude_rust_dyn_libs, b.Exclude_rust_dyn_libs...)
+	a.Exclude_binaries = append(a.Exclude_binaries, b.Exclude_binaries...)
+	a.Exclude_tests = append(a.Exclude_tests, b.Exclude_tests...)
+	a.Exclude_filesystems = append(a.Exclude_filesystems, b.Exclude_filesystems...)
 }
 
 type apexMultilibProperties struct {
@@ -675,12 +710,18 @@
 	// Use *FarVariation* to be able to depend on modules having conflicting variations with
 	// this module. This is required since arch variant of an APEX bundle is 'common' but it is
 	// 'arm' or 'arm64' for native shared libs.
-	ctx.AddFarVariationDependencies(binVariations, executableTag, nativeModules.Binaries...)
-	ctx.AddFarVariationDependencies(binVariations, testTag, nativeModules.Tests...)
-	ctx.AddFarVariationDependencies(libVariations, jniLibTag, nativeModules.Jni_libs...)
-	ctx.AddFarVariationDependencies(libVariations, sharedLibTag, nativeModules.Native_shared_libs...)
-	ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag, nativeModules.Rust_dyn_libs...)
-	ctx.AddFarVariationDependencies(target.Variations(), fsTag, nativeModules.Filesystems...)
+	ctx.AddFarVariationDependencies(binVariations, executableTag,
+		android.RemoveListFromList(nativeModules.Binaries, nativeModules.Exclude_binaries)...)
+	ctx.AddFarVariationDependencies(binVariations, testTag,
+		android.RemoveListFromList(nativeModules.Tests, nativeModules.Exclude_tests)...)
+	ctx.AddFarVariationDependencies(libVariations, jniLibTag,
+		android.RemoveListFromList(nativeModules.Jni_libs, nativeModules.Exclude_jni_libs)...)
+	ctx.AddFarVariationDependencies(libVariations, sharedLibTag,
+		android.RemoveListFromList(nativeModules.Native_shared_libs, nativeModules.Exclude_native_shared_libs)...)
+	ctx.AddFarVariationDependencies(rustLibVariations, sharedLibTag,
+		android.RemoveListFromList(nativeModules.Rust_dyn_libs, nativeModules.Exclude_rust_dyn_libs)...)
+	ctx.AddFarVariationDependencies(target.Variations(), fsTag,
+		android.RemoveListFromList(nativeModules.Filesystems, nativeModules.Exclude_filesystems)...)
 }
 
 func (a *apexBundle) combineProperties(ctx android.BottomUpMutatorContext) {
@@ -748,12 +789,12 @@
 			continue
 		}
 
-		var depsList []ApexNativeDependencies
+		var deps ApexNativeDependencies
 
 		// Add native modules targeting both ABIs. When multilib.* is omitted for
 		// native_shared_libs/jni_libs/tests, it implies multilib.both
-		depsList = append(depsList, a.properties.Multilib.Both)
-		depsList = append(depsList, ApexNativeDependencies{
+		deps.Merge(a.properties.Multilib.Both)
+		deps.Merge(ApexNativeDependencies{
 			Native_shared_libs: a.properties.Native_shared_libs,
 			Tests:              a.properties.Tests,
 			Jni_libs:           a.properties.Jni_libs,
@@ -764,8 +805,8 @@
 		// binaries, it implies multilib.first
 		isPrimaryAbi := i == 0
 		if isPrimaryAbi {
-			depsList = append(depsList, a.properties.Multilib.First)
-			depsList = append(depsList, ApexNativeDependencies{
+			deps.Merge(a.properties.Multilib.First)
+			deps.Merge(ApexNativeDependencies{
 				Native_shared_libs: nil,
 				Tests:              nil,
 				Jni_libs:           nil,
@@ -776,34 +817,32 @@
 		// Add native modules targeting either 32-bit or 64-bit ABI
 		switch target.Arch.ArchType.Multilib {
 		case "lib32":
-			depsList = append(depsList, a.properties.Multilib.Lib32)
-			depsList = append(depsList, a.properties.Multilib.Prefer32)
+			deps.Merge(a.properties.Multilib.Lib32)
+			deps.Merge(a.properties.Multilib.Prefer32)
 		case "lib64":
-			depsList = append(depsList, a.properties.Multilib.Lib64)
+			deps.Merge(a.properties.Multilib.Lib64)
 			if !has32BitTarget {
-				depsList = append(depsList, a.properties.Multilib.Prefer32)
+				deps.Merge(a.properties.Multilib.Prefer32)
 			}
 		}
 
 		// Add native modules targeting a specific arch variant
 		switch target.Arch.ArchType {
 		case android.Arm:
-			depsList = append(depsList, a.archProperties.Arch.Arm.ApexNativeDependencies)
+			deps.Merge(a.archProperties.Arch.Arm.ApexNativeDependencies)
 		case android.Arm64:
-			depsList = append(depsList, a.archProperties.Arch.Arm64.ApexNativeDependencies)
+			deps.Merge(a.archProperties.Arch.Arm64.ApexNativeDependencies)
 		case android.Riscv64:
-			depsList = append(depsList, a.archProperties.Arch.Riscv64.ApexNativeDependencies)
+			deps.Merge(a.archProperties.Arch.Riscv64.ApexNativeDependencies)
 		case android.X86:
-			depsList = append(depsList, a.archProperties.Arch.X86.ApexNativeDependencies)
+			deps.Merge(a.archProperties.Arch.X86.ApexNativeDependencies)
 		case android.X86_64:
-			depsList = append(depsList, a.archProperties.Arch.X86_64.ApexNativeDependencies)
+			deps.Merge(a.archProperties.Arch.X86_64.ApexNativeDependencies)
 		default:
 			panic(fmt.Errorf("unsupported arch %v\n", ctx.Arch().ArchType))
 		}
 
-		for _, d := range depsList {
-			addDependenciesForNativeModules(ctx, d, target, imageVariation)
-		}
+		addDependenciesForNativeModules(ctx, deps, target, imageVariation)
 		ctx.AddFarVariationDependencies([]blueprint.Variation{
 			{Mutator: "os", Variation: target.OsVariation()},
 			{Mutator: "arch", Variation: target.ArchVariation()},
@@ -2593,6 +2632,7 @@
 	module.AddProperties(
 		&apexBundleProperties{},
 		&apexTargetBundleProperties{},
+		&apexArchBundleProperties{},
 		&overridableProperties{},
 	)
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index b5b3c2f..10adf8d 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -4398,12 +4398,15 @@
 			name: "myapex",
 			key: "myapex.key",
 			updatable: false,
+			native_shared_libs: ["mylib.generic"],
 			arch: {
 				arm64: {
 					native_shared_libs: ["mylib.arm64"],
+					exclude_native_shared_libs: ["mylib.generic"],
 				},
 				x86_64: {
 					native_shared_libs: ["mylib.x64"],
+					exclude_native_shared_libs: ["mylib.generic"],
 				},
 			}
 		}
@@ -4415,6 +4418,18 @@
 		}
 
 		cc_library {
+			name: "mylib.generic",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			// TODO: remove //apex_available:platform
+			apex_available: [
+				"//apex_available:platform",
+				"myapex",
+			],
+		}
+
+		cc_library {
 			name: "mylib.arm64",
 			srcs: ["mylib.cpp"],
 			system_shared_libs: [],
@@ -4444,6 +4459,7 @@
 
 	// Ensure that apex variant is created for the direct dep
 	ensureListContains(t, ctx.ModuleVariantsForTests("mylib.arm64"), "android_arm64_armv8-a_shared_apex10000")
+	ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.generic"), "android_arm64_armv8-a_shared_apex10000")
 	ensureListNotContains(t, ctx.ModuleVariantsForTests("mylib.x64"), "android_arm64_armv8-a_shared_apex10000")
 
 	// Ensure that both direct and indirect deps are copied into apex
diff --git a/cc/config/global.go b/cc/config/global.go
index cf60414..9f18784 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -76,9 +76,6 @@
 		// Help catch common 32/64-bit errors.
 		"-Werror=int-conversion",
 
-		// Enable the new pass manager.
-		"-fexperimental-new-pass-manager",
-
 		// Disable overly aggressive warning for macros defined with a leading underscore
 		// This happens in AndroidConfig.h, which is included nearly everywhere.
 		// TODO: can we remove this now?
diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go
index eb71aa1..052832d 100644
--- a/cc/config/toolchain.go
+++ b/cc/config/toolchain.go
@@ -244,4 +244,8 @@
 	return LibclangRuntimeLibrary(t, "fuzzer")
 }
 
+func LibFuzzerRuntimeInterceptors(t Toolchain) string {
+	return LibclangRuntimeLibrary(t, "fuzzer_interceptors")
+}
+
 var inList = android.InList
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 0fbe45c..64bb7dd 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -126,6 +126,14 @@
 		deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers")
 	} else {
 		deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
+		// Fuzzers built with HWASAN should use the interceptors for better
+		// mutation based on signals in strcmp, memcpy, etc. This is only needed for
+		// fuzz targets, not generic HWASAN-ified binaries or libraries.
+		if module, ok := ctx.Module().(*Module); ok {
+			if module.IsSanitizerEnabled(Hwasan) {
+				deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeInterceptors(ctx.toolchain()))
+			}
+		}
 	}
 
 	deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
@@ -137,9 +145,18 @@
 	// RunPaths on devices isn't instantiated by the base linker. `../lib` for
 	// installed fuzz targets (both host and device), and `./lib` for fuzz
 	// target packages.
-	flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
 	flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
 
+	// When running on device, fuzz targets with vendor: true set will be in
+	// fuzzer_name/vendor/fuzzer_name (note the extra 'vendor' and thus need to
+	// link with libraries in ../../lib/. Non-vendor binaries only need to look
+	// one level up, in ../lib/.
+	if ctx.inVendor() {
+		flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../../lib`)
+	} else {
+		flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
+	}
+
 	return flags
 }
 
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 49a919e..d704e32 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -307,6 +307,7 @@
 	impl, ok := dep.(*Module)
 	if !ok {
 		ctx.ModuleErrorf("Implementation for stub is not correct module type")
+		return nil
 	}
 	output := impl.UnstrippedOutputFile()
 	if output == nil {
diff --git a/java/base.go b/java/base.go
index 96f36e8..602e8d8 100644
--- a/java/base.go
+++ b/java/base.go
@@ -593,6 +593,8 @@
 		return android.Paths{j.outputFile}, nil
 	case ".jar":
 		return android.Paths{j.implementationAndResourcesJar}, nil
+	case ".hjar":
+		return android.Paths{j.headerJarFile}, nil
 	case ".proguard_map":
 		if j.dexer.proguardDictionary.Valid() {
 			return android.Paths{j.dexer.proguardDictionary.Path()}, nil
diff --git a/licenses/Android.bp b/licenses/Android.bp
index 2e5c361..54981e1 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -1152,7 +1152,7 @@
 
 license_kind {
     name: "SPDX-license-identifier-WTFPL",
-    conditions: ["notice"],
+    conditions: ["permissive"],
     url: "https://spdx.org/licenses/WTFPL.html",
 }
 
diff --git a/symbol_inject/macho.go b/symbol_inject/macho.go
index 9946d34..ca3d50e 100644
--- a/symbol_inject/macho.go
+++ b/symbol_inject/macho.go
@@ -16,9 +16,12 @@
 
 import (
 	"debug/macho"
+	"encoding/binary"
 	"fmt"
 	"io"
+	"os"
 	"os/exec"
+	"path/filepath"
 	"sort"
 	"strings"
 )
@@ -98,6 +101,80 @@
 }
 
 func CodeSignMachoFile(path string) error {
-	cmd := exec.Command("/usr/bin/codesign", "--force", "-s", "-", path)
-	return cmd.Run()
+	filename := filepath.Base(path)
+	cmd := exec.Command("/usr/bin/codesign", "--force", "-s", "-", "-i", filename, path)
+	if err := cmd.Run(); err != nil {
+		return err
+	}
+	return modifyCodeSignFlags(path)
+}
+
+const LC_CODE_SIGNATURE = 0x1d
+const CSSLOT_CODEDIRECTORY = 0
+
+// To make codesign not invalidated by stripping, modify codesign flags to 0x20002
+// (adhoc | linkerSigned).
+func modifyCodeSignFlags(path string) error {
+	f, err := os.OpenFile(path, os.O_RDWR, 0)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+
+	// Step 1: find code signature section.
+	machoFile, err := macho.NewFile(f)
+	if err != nil {
+		return err
+	}
+	var codeSignSectionOffset uint32 = 0
+	var codeSignSectionSize uint32 = 0
+	for _, l := range machoFile.Loads {
+		data := l.Raw()
+		cmd := machoFile.ByteOrder.Uint32(data)
+		if cmd == LC_CODE_SIGNATURE {
+			codeSignSectionOffset = machoFile.ByteOrder.Uint32(data[8:])
+			codeSignSectionSize = machoFile.ByteOrder.Uint32(data[12:])
+		}
+	}
+	if codeSignSectionOffset == 0 {
+		return fmt.Errorf("code signature section not found")
+	}
+
+	data := make([]byte, codeSignSectionSize)
+	_, err = f.ReadAt(data, int64(codeSignSectionOffset))
+	if err != nil {
+		return err
+	}
+
+	// Step 2: get flags offset.
+	blobCount := binary.BigEndian.Uint32(data[8:])
+	off := 12
+	var codeDirectoryOff uint32 = 0
+	for blobCount > 0 {
+		blobType := binary.BigEndian.Uint32(data[off:])
+		if blobType == CSSLOT_CODEDIRECTORY {
+			codeDirectoryOff = binary.BigEndian.Uint32(data[off+4:])
+			break
+		}
+		blobCount--
+		off += 8
+	}
+	if codeDirectoryOff == 0 {
+		return fmt.Errorf("no code directory in code signature section")
+	}
+	flagsOff := codeSignSectionOffset + codeDirectoryOff + 12
+
+	// Step 3: modify flags.
+	flagsData := make([]byte, 4)
+	_, err = f.ReadAt(flagsData, int64(flagsOff))
+	if err != nil {
+		return err
+	}
+	oldFlags := binary.BigEndian.Uint32(flagsData)
+	if oldFlags != 0x2 {
+		return fmt.Errorf("unexpected flags in code signature section: 0x%x", oldFlags)
+	}
+	binary.BigEndian.PutUint32(flagsData, 0x20002)
+	_, err = f.WriteAt(flagsData, int64(flagsOff))
+	return err
 }
diff --git a/tests/bootstrap_test.sh b/tests/bootstrap_test.sh
index ba5ba8b..d89e6b7 100755
--- a/tests/bootstrap_test.sh
+++ b/tests/bootstrap_test.sh
@@ -285,6 +285,35 @@
 
 }
 
+function test_create_global_include_directory() {
+  setup
+  run_soong
+  local mtime1=$(stat -c "%y" out/soong/build.ninja)
+
+  # Soong needs to know if top level directories like hardware/ exist for use
+  # as global include directories.  Make sure that doesn't cause regens for
+  # unrelated changes to the top level directory.
+  mkdir -p system/core
+
+  run_soong
+  local mtime2=$(stat -c "%y" out/soong/build.ninja)
+  if [[ "$mtime1" != "$mtime2" ]]; then
+    fail "Output Ninja file changed when top level directory changed"
+  fi
+
+  # Make sure it does regen if a missing directory in the path of a global
+  # include directory is added.
+  mkdir -p system/core/include
+
+  run_soong
+  local mtime3=$(stat -c "%y" out/soong/build.ninja)
+  if [[ "$mtime2" = "$mtime3" ]]; then
+    fail "Output Ninja file did not change when global include directory created"
+  fi
+
+}
+
+
 function test_add_file_to_soong_build() {
   setup
   run_soong
@@ -874,6 +903,7 @@
 test_add_file_to_soong_build
 test_glob_during_bootstrapping
 test_soong_build_rerun_iff_environment_changes
+test_create_global_include_directory
 test_multiple_soong_build_modes
 test_dump_json_module_graph
 test_json_module_graph_back_and_forth_null_build