Merge "Convert abi warnings to errors."
diff --git a/android/androidmk.go b/android/androidmk.go
index 759d328..2cae1c3 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -231,10 +231,10 @@
if len(amod.commonProperties.Init_rc) > 0 {
fmt.Fprintln(&data.preamble, "LOCAL_INIT_RC := ", strings.Join(amod.commonProperties.Init_rc, " "))
}
- if amod.commonProperties.Proprietary {
+ if Bool(amod.commonProperties.Proprietary) {
fmt.Fprintln(&data.preamble, "LOCAL_PROPRIETARY_MODULE := true")
}
- if amod.commonProperties.Vendor {
+ if Bool(amod.commonProperties.Vendor) {
fmt.Fprintln(&data.preamble, "LOCAL_VENDOR_MODULE := true")
}
if amod.commonProperties.Owner != nil {
diff --git a/android/arch.go b/android/arch.go
index eaa35a4..f8317bb 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -312,12 +312,12 @@
var multilib string
switch class {
case Device:
- multilib = module.base().commonProperties.Target.Android.Compile_multilib
+ multilib = String(module.base().commonProperties.Target.Android.Compile_multilib)
case Host, HostCross:
- multilib = module.base().commonProperties.Target.Host.Compile_multilib
+ multilib = String(module.base().commonProperties.Target.Host.Compile_multilib)
}
if multilib == "" {
- multilib = module.base().commonProperties.Compile_multilib
+ multilib = String(module.base().commonProperties.Compile_multilib)
}
if multilib == "" {
multilib = module.base().commonProperties.Default_multilib
diff --git a/android/config.go b/android/config.go
index 56d0a39..e9a8d42 100644
--- a/android/config.go
+++ b/android/config.go
@@ -504,6 +504,10 @@
return Bool(c.ProductVariables.Pdk)
}
+func (c *config) MinimizeJavaDebugInfo() bool {
+ return Bool(c.ProductVariables.MinimizeJavaDebugInfo) && !Bool(c.ProductVariables.Eng)
+}
+
func (c *config) DevicePrefer32BitExecutables() bool {
return Bool(c.ProductVariables.DevicePrefer32BitExecutables)
}
diff --git a/android/module.go b/android/module.go
index 1cdc2dd..b8c9ab2 100644
--- a/android/module.go
+++ b/android/module.go
@@ -165,27 +165,27 @@
// are "32" (compile for 32-bit only), "64" (compile for 64-bit only), "both" (compile for both
// architectures), or "first" (compile for 64-bit on a 64-bit platform, and 32-bit on a 32-bit
// platform
- Compile_multilib string `android:"arch_variant"`
+ Compile_multilib *string `android:"arch_variant"`
Target struct {
Host struct {
- Compile_multilib string
+ Compile_multilib *string
}
Android struct {
- Compile_multilib string
+ Compile_multilib *string
}
}
Default_multilib string `blueprint:"mutated"`
// whether this is a proprietary vendor module, and should be installed into /vendor
- Proprietary bool
+ Proprietary *bool
// vendor who owns this module
Owner *string
// whether this module is device specific and should be installed into /vendor
- Vendor bool
+ Vendor *bool
// *.logtags files, to combine together in order to generate the /system/etc/event-log-tags
// file
@@ -519,7 +519,7 @@
return androidBaseContextImpl{
target: a.commonProperties.CompileTarget,
targetPrimary: a.commonProperties.CompilePrimary,
- vendor: a.commonProperties.Proprietary || a.commonProperties.Vendor,
+ vendor: Bool(a.commonProperties.Proprietary) || Bool(a.commonProperties.Vendor),
config: ctx.Config().(Config),
}
}
diff --git a/android/variable.go b/android/variable.go
index 4b3925c..28841e2 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -158,6 +158,7 @@
Treble *bool `json:",omitempty"`
Pdk *bool `json:",omitempty"`
Uml *bool `json:",omitempty"`
+ MinimizeJavaDebugInfo *bool `json:",omitempty"`
IntegerOverflowExcludePaths *[]string `json:",omitempty"`
diff --git a/cc/cc.go b/cc/cc.go
index cdbe43e..02aaf19 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -46,6 +46,9 @@
ctx.TopDown("asan_deps", sanitizerDepsMutator(asan))
ctx.BottomUp("asan", sanitizerMutator(asan)).Parallel()
+ ctx.TopDown("cfi_deps", sanitizerDepsMutator(cfi))
+ ctx.BottomUp("cfi", sanitizerMutator(cfi)).Parallel()
+
ctx.TopDown("tsan_deps", sanitizerDepsMutator(tsan))
ctx.BottomUp("tsan", sanitizerMutator(tsan)).Parallel()
@@ -437,12 +440,7 @@
}
func (ctx *moduleContextImpl) static() bool {
- if static, ok := ctx.mod.linker.(interface {
- static() bool
- }); ok {
- return static.static()
- }
- return false
+ return ctx.mod.static()
}
func (ctx *moduleContextImpl) staticBinary() bool {
@@ -1281,6 +1279,15 @@
return android.Paths{}
}
+func (c *Module) static() bool {
+ if static, ok := c.linker.(interface {
+ static() bool
+ }); ok {
+ return static.static()
+ }
+ return false
+}
+
//
// Defaults
//
diff --git a/cc/config/cfi_exports.map b/cc/config/cfi_exports.map
new file mode 100644
index 0000000..3d8f3e0
--- /dev/null
+++ b/cc/config/cfi_exports.map
@@ -0,0 +1,4 @@
+{
+ global:
+ __cfi_check;
+};
diff --git a/cc/library.go b/cc/library.go
index 25872c6..9d18017 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -513,6 +513,10 @@
if versionScript.Valid() {
flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+versionScript.String())
linkerDeps = append(linkerDeps, versionScript.Path())
+ if library.sanitize.isSanitizerEnabled(cfi) {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--version-script,"+cfiExportsMap.String())
+ linkerDeps = append(linkerDeps, cfiExportsMap)
+ }
}
if unexportedSymbols.Valid() {
ctx.PropertyErrorf("unexported_symbols_list", "Only supported on Darwin")
diff --git a/cc/sanitize.go b/cc/sanitize.go
index d5535cb..7d2b1ca 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -32,12 +32,14 @@
asanLdflags = []string{"-Wl,-u,__asan_preinit"}
asanLibs = []string{"libasan"}
- cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fvisibility=default",
+ cfiCflags = []string{"-flto", "-fsanitize-cfi-cross-dso",
"-fsanitize-blacklist=external/compiler-rt/lib/cfi/cfi_blacklist.txt"}
// FIXME: revert the __cfi_check flag when clang is updated to r280031.
cfiLdflags = []string{"-flto", "-fsanitize-cfi-cross-dso", "-fsanitize=cfi",
"-Wl,-plugin-opt,O1 -Wl,-export-dynamic-symbol=__cfi_check"}
- cfiArflags = []string{"--plugin ${config.ClangBin}/../lib64/LLVMgold.so"}
+ cfiArflags = []string{"--plugin ${config.ClangBin}/../lib64/LLVMgold.so"}
+ cfiExportsMapPath = "build/soong/cc/config/cfi_exports.map"
+ cfiExportsMap android.Path
intOverflowCflags = []string{"-fsanitize-blacklist=build/soong/cc/config/integer_overflow_blacklist.txt"}
)
@@ -56,6 +58,7 @@
asan sanitizerType = iota + 1
tsan
intOverflow
+ cfi
)
func (t sanitizerType) String() string {
@@ -66,6 +69,8 @@
return "tsan"
case intOverflow:
return "intOverflow"
+ case cfi:
+ return "cfi"
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -251,6 +256,8 @@
ctx.ModuleErrorf(`Use of "coverage" also requires "address"`)
}
}
+
+ cfiExportsMap = android.PathForSource(ctx, cfiExportsMapPath)
}
func (sanitize *sanitize) deps(ctx BaseModuleContext, deps Deps) Deps {
@@ -362,12 +369,23 @@
flags.LdFlags = append(flags.LdFlags, "-march=armv7-a")
}
sanitizers = append(sanitizers, "cfi")
+
flags.CFlags = append(flags.CFlags, cfiCflags...)
+ // Only append the default visibility flag if -fvisibility has not already been set
+ // to hidden.
+ if !inList("-fvisibility=hidden", flags.CFlags) {
+ flags.CFlags = append(flags.CFlags, "-fvisibility=default")
+ }
flags.LdFlags = append(flags.LdFlags, cfiLdflags...)
flags.ArFlags = append(flags.ArFlags, cfiArflags...)
if Bool(sanitize.Properties.Sanitize.Diag.Cfi) {
diagSanitizers = append(diagSanitizers, "cfi")
}
+
+ if ctx.staticBinary() {
+ _, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags)
+ _, flags.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.LdFlags)
+ }
}
if Bool(sanitize.Properties.Sanitize.Integer_overflow) {
@@ -445,24 +463,30 @@
fmt.Fprintln(w, "LOCAL_SHARED_LIBRARIES += "+sanitize.androidMkRuntimeLibrary)
}
})
+ if ctx.Target().Os.Class == android.Device {
+ if Bool(sanitize.Properties.Sanitize.Cfi) {
+ ret.SubName += ".cfi"
+ } else if Bool(sanitize.Properties.Sanitize.Address) {
+ ret.SubName += ".asan"
+ }
+ }
+
}
func (sanitize *sanitize) inSanitizerDir() bool {
return sanitize.Properties.InSanitizerDir
}
-func (sanitize *sanitize) Sanitizer(t sanitizerType) bool {
- if sanitize == nil {
- return false
- }
-
+func (sanitize *sanitize) getSanitizerBoolPtr(t sanitizerType) *bool {
switch t {
case asan:
- return Bool(sanitize.Properties.Sanitize.Address)
+ return sanitize.Properties.Sanitize.Address
case tsan:
- return Bool(sanitize.Properties.Sanitize.Thread)
+ return sanitize.Properties.Sanitize.Thread
case intOverflow:
- return Bool(sanitize.Properties.Sanitize.Integer_overflow)
+ return sanitize.Properties.Sanitize.Integer_overflow
+ case cfi:
+ return sanitize.Properties.Sanitize.Cfi
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -479,6 +503,9 @@
sanitize.Properties.Sanitize.Thread = boolPtr(b)
case intOverflow:
sanitize.Properties.Sanitize.Integer_overflow = boolPtr(b)
+ case cfi:
+ sanitize.Properties.Sanitize.Cfi = boolPtr(b)
+ sanitize.Properties.Sanitize.Diag.Cfi = boolPtr(b)
default:
panic(fmt.Errorf("unknown sanitizerType %d", t))
}
@@ -487,40 +514,87 @@
}
}
+// Check if the sanitizer is explicitly disabled (as opposed to nil by
+// virtue of not being set).
+func (sanitize *sanitize) isSanitizerExplicitlyDisabled(t sanitizerType) bool {
+ if sanitize == nil {
+ return false
+ }
+
+ sanitizerVal := sanitize.getSanitizerBoolPtr(t)
+ return sanitizerVal != nil && *sanitizerVal == false
+}
+
+// There isn't an analog of the method above (ie:isSanitizerExplicitlyEnabled)
+// because enabling a sanitizer either directly (via the blueprint) or
+// indirectly (via a mutator) sets the bool ptr to true, and you can't
+// distinguish between the cases. It isn't needed though - both cases can be
+// treated identically.
+func (sanitize *sanitize) isSanitizerEnabled(t sanitizerType) bool {
+ if sanitize == nil {
+ return false
+ }
+
+ sanitizerVal := sanitize.getSanitizerBoolPtr(t)
+ return sanitizerVal != nil && *sanitizerVal == true
+}
+
// Propagate asan requirements down from binaries
func sanitizerDepsMutator(t sanitizerType) func(android.TopDownMutatorContext) {
return func(mctx android.TopDownMutatorContext) {
- if c, ok := mctx.Module().(*Module); ok && c.sanitize.Sanitizer(t) {
+ if c, ok := mctx.Module().(*Module); ok && c.sanitize.isSanitizerEnabled(t) {
mctx.VisitDepsDepthFirst(func(module android.Module) {
- if d, ok := mctx.Module().(*Module); ok && c.sanitize != nil &&
- !c.sanitize.Properties.Sanitize.Never {
- d.sanitize.Properties.SanitizeDep = true
+ if d, ok := module.(*Module); ok && d.sanitize != nil &&
+ !d.sanitize.Properties.Sanitize.Never &&
+ !d.sanitize.isSanitizerExplicitlyDisabled(t) {
+ if (t == cfi && d.static()) || t != cfi {
+ d.sanitize.Properties.SanitizeDep = true
+ }
}
})
}
}
}
-// Create asan variants for modules that need them
+// Create sanitized variants for modules that need them
func sanitizerMutator(t sanitizerType) func(android.BottomUpMutatorContext) {
return func(mctx android.BottomUpMutatorContext) {
if c, ok := mctx.Module().(*Module); ok && c.sanitize != nil {
- if c.isDependencyRoot() && c.sanitize.Sanitizer(t) {
+ if c.isDependencyRoot() && c.sanitize.isSanitizerEnabled(t) {
modules := mctx.CreateVariations(t.String())
modules[0].(*Module).sanitize.SetSanitizer(t, true)
- } else if c.sanitize.Properties.SanitizeDep {
+ } 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)
+
modules := mctx.CreateVariations("", t.String())
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
if mctx.Device() {
- modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
+ // CFI and ASAN are currently mutually exclusive so disable
+ // CFI if this is an ASAN variant.
+ if t == asan {
+ modules[1].(*Module).sanitize.Properties.InSanitizerDir = true
+ modules[1].(*Module).sanitize.SetSanitizer(cfi, false)
+ }
} else {
- modules[0].(*Module).Properties.PreventInstall = true
- }
- if mctx.AConfig().EmbeddedInMake() {
- modules[0].(*Module).Properties.HideFromMake = true
+ if isSanitizerEnabled {
+ modules[0].(*Module).Properties.PreventInstall = true
+ } else {
+ modules[1].(*Module).Properties.PreventInstall = true
+ }
+
+ if mctx.AConfig().EmbeddedInMake() {
+ if isSanitizerEnabled {
+ modules[0].(*Module).Properties.HideFromMake = true
+ } else {
+ modules[1].(*Module).Properties.HideFromMake = true
+ }
+ }
}
}
c.sanitize.Properties.SanitizeDep = false
diff --git a/java/java.go b/java/java.go
index 7ecf672..1541dec 100644
--- a/java/java.go
+++ b/java/java.go
@@ -466,6 +466,11 @@
if ctx.AConfig().TargetOpenJDK9() {
javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...)
}
+ if ctx.AConfig().MinimizeJavaDebugInfo() {
+ // Override the -g flag passed globally to remove local variable debug info to reduce
+ // disk and memory usage.
+ javacFlags = append(javacFlags, "-g:source,lines")
+ }
if len(javacFlags) > 0 {
// optimization.
ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " "))