Merge "Include headers and props to VNDK snapshot"
diff --git a/README.md b/README.md
index 60d7d5a..18422ea 100644
--- a/README.md
+++ b/README.md
@@ -355,6 +355,18 @@
 dlv connect :1234
 ```
 
+If you see an error:
+```
+Could not attach to pid 593: this could be caused by a kernel
+security setting, try writing "0" to /proc/sys/kernel/yama/ptrace_scope
+```
+you can temporarily disable
+[Yama's ptrace protection](https://www.kernel.org/doc/Documentation/security/Yama.txt)
+using:
+```bash
+sudo sysctl -w kernel.yama.ptrace_scope=0
+```
+
 ## Contact
 
 Email android-building@googlegroups.com (external) for any questions, or see
diff --git a/android/config.go b/android/config.go
index a8b59d3..72372ef 100644
--- a/android/config.go
+++ b/android/config.go
@@ -689,10 +689,6 @@
 	return c.Targets[Android][0].Arch.ArchType
 }
 
-func (c *config) SkipDeviceInstall() bool {
-	return c.EmbeddedInMake()
-}
-
 func (c *config) SkipMegaDeviceInstall(path string) bool {
 	return Bool(c.Mega_device) &&
 		strings.HasPrefix(path, filepath.Join(c.buildDir, "target", "product"))
diff --git a/android/module.go b/android/module.go
index 138b9cd..990a893 100644
--- a/android/module.go
+++ b/android/module.go
@@ -155,6 +155,7 @@
 	InstallInData() bool
 	InstallInSanitizerDir() bool
 	InstallInRecovery() bool
+	InstallBypassMake() bool
 
 	RequiredModuleNames() []string
 	HostRequiredModuleNames() []string
@@ -192,6 +193,7 @@
 	InstallInData() bool
 	InstallInSanitizerDir() bool
 	InstallInRecovery() bool
+	InstallBypassMake() bool
 	SkipInstall()
 	ExportedToMake() bool
 	NoticeFile() OptionalPath
@@ -837,6 +839,10 @@
 	return Bool(m.commonProperties.Recovery)
 }
 
+func (m *ModuleBase) InstallBypassMake() bool {
+	return false
+}
+
 func (m *ModuleBase) Owner() string {
 	return String(m.commonProperties.Owner)
 }
@@ -1493,6 +1499,10 @@
 	return m.module.InstallInRecovery()
 }
 
+func (m *moduleContext) InstallBypassMake() bool {
+	return m.module.InstallBypassMake()
+}
+
 func (m *moduleContext) skipInstall(fullInstallPath OutputPath) bool {
 	if m.module.base().commonProperties.SkipInstall {
 		return true
@@ -1506,7 +1516,7 @@
 	}
 
 	if m.Device() {
-		if m.Config().SkipDeviceInstall() {
+		if m.Config().EmbeddedInMake() && !m.InstallBypassMake() {
 			return true
 		}
 
diff --git a/android/mutator.go b/android/mutator.go
index 82376e4..8e4343d 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -143,6 +143,7 @@
 	CreateVariations(...string) []blueprint.Module
 	CreateLocalVariations(...string) []blueprint.Module
 	SetDependencyVariation(string)
+	SetDefaultDependencyVariation(*string)
 	AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
 	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string)
 	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module)
@@ -292,6 +293,10 @@
 	b.bp.SetDependencyVariation(variation)
 }
 
+func (b *bottomUpMutatorContext) SetDefaultDependencyVariation(variation *string) {
+	b.bp.SetDefaultDependencyVariation(variation)
+}
+
 func (b *bottomUpMutatorContext) AddVariationDependencies(variations []blueprint.Variation, tag blueprint.DependencyTag,
 	names ...string) {
 
diff --git a/android/paths.go b/android/paths.go
index e3f0544..0d99918 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -46,6 +46,7 @@
 	InstallInData() bool
 	InstallInSanitizerDir() bool
 	InstallInRecovery() bool
+	InstallBypassMake() bool
 }
 
 var _ ModuleInstallPathContext = ModuleContext(nil)
@@ -818,6 +819,17 @@
 	return OutputPath{basePath{path, ctx.Config(), ""}}
 }
 
+// pathForInstallInMakeDir is used by PathForModuleInstall when the module returns true
+// for InstallBypassMake to produce an OutputPath that installs to $OUT_DIR instead of
+// $OUT_DIR/soong.
+func pathForInstallInMakeDir(ctx PathContext, pathComponents ...string) OutputPath {
+	path, err := validatePath(pathComponents...)
+	if err != nil {
+		reportPathError(ctx, err)
+	}
+	return OutputPath{basePath{"../" + path, ctx.Config(), ""}}
+}
+
 // PathsForOutput returns Paths rooted from buildDir
 func PathsForOutput(ctx PathContext, paths []string) WritablePaths {
 	ret := make(WritablePaths, len(paths))
@@ -1123,6 +1135,9 @@
 		outPaths = append([]string{"debug"}, outPaths...)
 	}
 	outPaths = append(outPaths, pathComponents...)
+	if ctx.InstallBypassMake() && ctx.Config().EmbeddedInMake() {
+		return pathForInstallInMakeDir(ctx, outPaths...)
+	}
 	return PathForOutput(ctx, outPaths...)
 }
 
diff --git a/android/paths_test.go b/android/paths_test.go
index 8286e9a..f2996bf 100644
--- a/android/paths_test.go
+++ b/android/paths_test.go
@@ -227,6 +227,10 @@
 	return m.inRecovery
 }
 
+func (m moduleInstallPathContextImpl) InstallBypassMake() bool {
+	return false
+}
+
 func TestPathForModuleInstall(t *testing.T) {
 	testConfig := TestConfig("", nil)
 
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 38d2bf2..f034f2a 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -30,6 +30,16 @@
 
 var buildDir string
 
+// names returns name list from white space separated string
+func names(s string) (ns []string) {
+	for _, n := range strings.Split(s, " ") {
+		if len(n) > 0 {
+			ns = append(ns, n)
+		}
+	}
+	return
+}
+
 func testApexError(t *testing.T, pattern, bp string) {
 	ctx, config := testApexContext(t, bp)
 	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
@@ -626,6 +636,73 @@
 	ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
 }
 
+func TestApexWithRuntimeLibsDependency(t *testing.T) {
+	/*
+		myapex
+		  |
+		  v   (runtime_libs)
+		mylib ------+------> libfoo [provides stub]
+			    |
+			    `------> libbar
+	*/
+	ctx, _ := testApex(t, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["mylib"],
+		}
+
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}
+
+		cc_library {
+			name: "mylib",
+			srcs: ["mylib.cpp"],
+			runtime_libs: ["libfoo", "libbar"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+		cc_library {
+			name: "libfoo",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+			stubs: {
+				versions: ["10", "20", "30"],
+			},
+		}
+
+		cc_library {
+			name: "libbar",
+			srcs: ["mylib.cpp"],
+			system_shared_libs: [],
+			stl: "none",
+		}
+
+	`)
+
+	apexRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("apexRule")
+	copyCmds := apexRule.Args["copy_commands"]
+
+	// Ensure that direct non-stubs dep is always included
+	ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+
+	// Ensure that indirect stubs dep is not included
+	ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.so")
+
+	// Ensure that runtime_libs dep in included
+	ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
+
+	injectRule := ctx.ModuleForTests("myapex", "android_common_myapex").Rule("injectApexDependency")
+	ensureListEmpty(t, names(injectRule.Args["provideNativeLibs"]))
+	ensureListContains(t, names(injectRule.Args["requireNativeLibs"]), "libfoo.so")
+
+}
+
 func TestApexWithSystemLibsStubs(t *testing.T) {
 	ctx, _ := testApex(t, `
 		apex {
@@ -1133,15 +1210,6 @@
 		}
 	`)
 
-	names := func(s string) (ns []string) {
-		for _, n := range strings.Split(s, " ") {
-			if len(n) > 0 {
-				ns = append(ns, n)
-			}
-		}
-		return
-	}
-
 	var injectRule android.TestingBuildParams
 	var provideNativeLibs, requireNativeLibs []string
 
diff --git a/cc/builder.go b/cc/builder.go
index 2909d51..89c418b 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -498,7 +498,9 @@
 				Input:       srcFile,
 				// We must depend on objFile, since clang-tidy doesn't
 				// support exporting dependencies.
-				Implicit: objFile,
+				Implicit:  objFile,
+				Implicits: cFlagsDeps,
+				OrderOnly: pathDeps,
 				Args: map[string]string{
 					"cFlags":    moduleToolingCflags,
 					"tidyFlags": flags.tidyFlags,
@@ -516,6 +518,8 @@
 				Output:      sAbiDumpFile,
 				Input:       srcFile,
 				Implicit:    objFile,
+				Implicits:   cFlagsDeps,
+				OrderOnly:   pathDeps,
 				Args: map[string]string{
 					"cFlags":     moduleToolingCflags,
 					"exportDirs": flags.sAbiFlags,
diff --git a/cc/cc.go b/cc/cc.go
index 2bde2d3..b637d3e 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -56,6 +56,8 @@
 		ctx.TopDown("fuzzer_deps", sanitizerDepsMutator(fuzzer))
 		ctx.BottomUp("fuzzer", sanitizerMutator(fuzzer)).Parallel()
 
+		// cfi mutator shouldn't run before sanitizers that return true for
+		// incompatibleWithCfi()
 		ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
 		ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
 
@@ -255,6 +257,7 @@
 type ModuleContextIntf interface {
 	static() bool
 	staticBinary() bool
+	header() bool
 	toolchain() config.Toolchain
 	useSdk() bool
 	sdkVersion() string
@@ -715,6 +718,10 @@
 	return ctx.mod.staticBinary()
 }
 
+func (ctx *moduleContextImpl) header() bool {
+	return ctx.mod.header()
+}
+
 func (ctx *moduleContextImpl) useSdk() bool {
 	if ctx.ctx.Device() && !ctx.useVndk() && !ctx.inRecovery() && !ctx.ctx.Fuchsia() {
 		return String(ctx.mod.Properties.Sdk_version) != ""
@@ -2023,6 +2030,15 @@
 	return false
 }
 
+func (c *Module) header() bool {
+	if h, ok := c.linker.(interface {
+		header() bool
+	}); ok {
+		return h.header()
+	}
+	return false
+}
+
 func (c *Module) getMakeLinkType(actx android.ModuleContext) string {
 	name := actx.ModuleName()
 	if c.useVndk() {
diff --git a/cc/compiler.go b/cc/compiler.go
index ffb6ad2..85ff400 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -309,6 +309,7 @@
 		flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
 			"-isystem "+getCurrentIncludePath(ctx).String(),
 			"-isystem "+getCurrentIncludePath(ctx).Join(ctx, config.NDKTriple(tc)).String())
+		flags.GlobalFlags = append(flags.GlobalFlags, "-D__ANDROID_NDK__")
 	}
 
 	if ctx.useVndk() {
diff --git a/cc/llndk_library.go b/cc/llndk_library.go
index 8290103..4d59975 100644
--- a/cc/llndk_library.go
+++ b/cc/llndk_library.go
@@ -232,7 +232,7 @@
 		&library.MutatedProperties,
 		&library.flagExporter.Properties)
 
-	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibBoth)
+	module.Init()
 
 	return module
 }
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 261ca88..a017824 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -124,6 +124,10 @@
 	}
 }
 
+func (t sanitizerType) incompatibleWithCfi() bool {
+	return t == asan || t == fuzzer || t == hwasan
+}
+
 type SanitizeProperties struct {
 	// enable AddressSanitizer, ThreadSanitizer, or UndefinedBehaviorSanitizer
 	Sanitize struct {
@@ -556,16 +560,18 @@
 }
 
 func (sanitize *sanitize) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkData) {
-	// Add a suffix for CFI-enabled static libraries to allow surfacing both to make without a
-	// name conflict.
-	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Cfi) {
-		ret.SubName += ".cfi"
-	}
-	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Hwaddress) {
-		ret.SubName += ".hwasan"
-	}
-	if ret.Class == "STATIC_LIBRARIES" && Bool(sanitize.Properties.Sanitize.Scs) {
-		ret.SubName += ".scs"
+	// Add a suffix for cfi/hwasan/scs-enabled static/header libraries to allow surfacing
+	// both the sanitized and non-sanitized variants to make without a name conflict.
+	if ret.Class == "STATIC_LIBRARIES" || ret.Class == "HEADER_LIBRARIES" {
+		if Bool(sanitize.Properties.Sanitize.Cfi) {
+			ret.SubName += ".cfi"
+		}
+		if Bool(sanitize.Properties.Sanitize.Hwaddress) {
+			ret.SubName += ".hwasan"
+		}
+		if Bool(sanitize.Properties.Sanitize.Scs) {
+			ret.SubName += ".scs"
+		}
 	}
 }
 
@@ -870,7 +876,7 @@
 					{Mutator: "image", Variation: c.imageVariation()},
 					{Mutator: "arch", Variation: mctx.Target().String()},
 				}, staticDepTag, runtimeLibrary)
-			} else if !c.static() {
+			} else if !c.static() && !c.header() {
 				// dynamic executable and shared libs get shared runtime libs
 				mctx.AddFarVariationDependencies([]blueprint.Variation{
 					{Mutator: "link", Variation: "shared"},
@@ -899,108 +905,69 @@
 				modules := mctx.CreateVariations(t.variationName())
 				modules[0].(*Module).sanitize.SetSanitizer(t, true)
 			} else if c.sanitize.isSanitizerEnabled(t) || c.sanitize.Properties.SanitizeDep {
-				// Save original sanitizer status before we assign values to variant
-				// 0 as that overwrites the original.
 				isSanitizerEnabled := c.sanitize.isSanitizerEnabled(t)
+				if mctx.Device() && t.incompatibleWithCfi() {
+					// TODO: Make sure that cfi mutator runs "after" any of the sanitizers that
+					// are incompatible with cfi
+					c.sanitize.SetSanitizer(cfi, false)
+				}
+				if c.static() || c.header() || t == asan || t == fuzzer {
+					// Static and header libs are split into non-sanitized and sanitized variants.
+					// Shared libs are not split. However, for asan and fuzzer, we split even for shared
+					// libs because a library sanitized for asan/fuzzer can't be linked from a library
+					// that isn't sanitized for asan/fuzzer.
+					//
+					// Note for defaultVariation: since we don't split for shared libs but for static/header
+					// libs, it is possible for the sanitized variant of a static/header lib to depend
+					// on non-sanitized variant of a shared lib. Such unfulfilled variation causes an
+					// error when the module is split. defaultVariation is the name of the variation that
+					// will be used when such a dangling dependency occurs during the split of the current
+					// module. By setting it to the name of the sanitized variation, the dangling dependency
+					// is redirected to the sanitized variant of the dependent module.
+					defaultVariation := t.variationName()
+					mctx.SetDefaultDependencyVariation(&defaultVariation)
+					modules := mctx.CreateVariations("", t.variationName())
+					modules[0].(*Module).sanitize.SetSanitizer(t, false)
+					modules[1].(*Module).sanitize.SetSanitizer(t, true)
+					modules[0].(*Module).sanitize.Properties.SanitizeDep = false
+					modules[1].(*Module).sanitize.Properties.SanitizeDep = false
 
-				modules := mctx.CreateVariations("", t.variationName())
-				modules[0].(*Module).sanitize.SetSanitizer(t, false)
-				modules[1].(*Module).sanitize.SetSanitizer(t, true)
+					// For cfi/scs/hwasan, we can export both sanitized and un-sanitized variants
+					// to Make, because the sanitized version has a different suffix in name.
+					// For other types of sanitizers, suppress the variation that is disabled.
+					if t != cfi && t != scs && t != hwasan {
+						if isSanitizerEnabled {
+							modules[0].(*Module).Properties.PreventInstall = true
+							modules[0].(*Module).Properties.HideFromMake = true
+						} else {
+							modules[1].(*Module).Properties.PreventInstall = true
+							modules[1].(*Module).Properties.HideFromMake = true
+						}
+					}
 
-				modules[0].(*Module).sanitize.Properties.SanitizeDep = false
-				modules[1].(*Module).sanitize.Properties.SanitizeDep = false
-
-				// We don't need both variants active for anything but CFI-enabled
-				// target static libraries, so suppress the appropriate variant in
-				// all other cases.
-				if t == cfi {
+					// Export the static lib name to make
 					if c.static() {
-						if !mctx.Device() {
-							if isSanitizerEnabled {
-								modules[0].(*Module).Properties.PreventInstall = true
-								modules[0].(*Module).Properties.HideFromMake = true
+						if t == cfi {
+							appendStringSync(c.Name(), cfiStaticLibs(mctx.Config()), &cfiStaticLibsMutex)
+						} else if t == hwasan {
+							if c.useVndk() {
+								appendStringSync(c.Name(), hwasanVendorStaticLibs(mctx.Config()),
+									&hwasanStaticLibsMutex)
 							} else {
-								modules[1].(*Module).Properties.PreventInstall = true
-								modules[1].(*Module).Properties.HideFromMake = true
+								appendStringSync(c.Name(), hwasanStaticLibs(mctx.Config()),
+									&hwasanStaticLibsMutex)
 							}
-						} else {
-							cfiStaticLibs := cfiStaticLibs(mctx.Config())
+						}
+					}
+				} else {
+					// Shared libs are not split. Only the sanitized variant is created.
+					modules := mctx.CreateVariations(t.variationName())
+					modules[0].(*Module).sanitize.SetSanitizer(t, true)
+					modules[0].(*Module).sanitize.Properties.SanitizeDep = false
 
-							cfiStaticLibsMutex.Lock()
-							*cfiStaticLibs = append(*cfiStaticLibs, c.Name())
-							cfiStaticLibsMutex.Unlock()
-						}
-					} else {
-						modules[0].(*Module).Properties.PreventInstall = true
-						modules[0].(*Module).Properties.HideFromMake = true
-					}
-				} else if t == asan {
-					if mctx.Device() {
-						// CFI and ASAN are currently mutually exclusive so disable
-						// CFI if this is an ASAN variant.
-						modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
-						modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
-					}
-					if isSanitizerEnabled {
-						modules[0].(*Module).Properties.PreventInstall = true
-						modules[0].(*Module).Properties.HideFromMake = true
-					} else {
-						modules[1].(*Module).Properties.PreventInstall = true
-						modules[1].(*Module).Properties.HideFromMake = true
-					}
-				} else if t == scs {
-					// We don't currently link any static libraries built with make into
-					// libraries built with SCS, so we don't need logic for propagating
-					// SCSness of dependencies into make.
-					if !c.static() {
-						if isSanitizerEnabled {
-							modules[0].(*Module).Properties.PreventInstall = true
-							modules[0].(*Module).Properties.HideFromMake = true
-						} else {
-							modules[1].(*Module).Properties.PreventInstall = true
-							modules[1].(*Module).Properties.HideFromMake = true
-						}
-					}
-				} else if t == fuzzer {
-					// TODO(b/131771163): CFI and fuzzer support are mutually incompatible
-					// as CFI pulls in LTO.
-					if mctx.Device() {
-						modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
-					}
-					if isSanitizerEnabled {
-						modules[0].(*Module).Properties.PreventInstall = true
-						modules[0].(*Module).Properties.HideFromMake = true
-					} else {
-						modules[1].(*Module).Properties.PreventInstall = true
-						modules[1].(*Module).Properties.HideFromMake = true
-					}
-				} else if t == hwasan {
-					if mctx.Device() {
-						// CFI and HWASAN are currently mutually exclusive so disable
-						// CFI if this is an HWASAN variant.
-						modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
-					}
-
-					if c.static() {
-						if c.useVndk() {
-							hwasanVendorStaticLibs := hwasanVendorStaticLibs(mctx.Config())
-							hwasanStaticLibsMutex.Lock()
-							*hwasanVendorStaticLibs = append(*hwasanVendorStaticLibs, c.Name())
-							hwasanStaticLibsMutex.Unlock()
-						} else {
-							hwasanStaticLibs := hwasanStaticLibs(mctx.Config())
-							hwasanStaticLibsMutex.Lock()
-							*hwasanStaticLibs = append(*hwasanStaticLibs, c.Name())
-							hwasanStaticLibsMutex.Unlock()
-						}
-					} else {
-						if isSanitizerEnabled {
-							modules[0].(*Module).Properties.PreventInstall = true
-							modules[0].(*Module).Properties.HideFromMake = true
-						} else {
-							modules[1].(*Module).Properties.PreventInstall = true
-							modules[1].(*Module).Properties.HideFromMake = true
-						}
+					// locate the asan libraries under /data/asan
+					if mctx.Device() && t == asan && isSanitizerEnabled {
+						modules[0].(*Module).sanitize.Properties.InSanitizerDir = true
 					}
 				}
 			}
@@ -1036,6 +1003,12 @@
 	}).(*[]string)
 }
 
+func appendStringSync(item string, list *[]string, mutex *sync.Mutex) {
+	mutex.Lock()
+	*list = append(*list, item)
+	mutex.Unlock()
+}
+
 func enableMinimalRuntime(sanitize *sanitize) bool {
 	if !Bool(sanitize.Properties.Sanitize.Address) &&
 		!Bool(sanitize.Properties.Sanitize.Hwaddress) &&
diff --git a/java/java.go b/java/java.go
index fea38b5..3b789f6 100644
--- a/java/java.go
+++ b/java/java.go
@@ -370,6 +370,8 @@
 		return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil
 	case ".jar":
 		return android.Paths{j.implementationAndResourcesJar}, nil
+	case ".proguard_map":
+		return android.Paths{j.proguardDictionary}, nil
 	default:
 		return nil, fmt.Errorf("unsupported module reference tag %q", tag)
 	}