Add support for AArch64 XOM binaries.
Adds build system support for generating AArch64 binaries with
execute-only memory layouts via a new xom module property. Also adds
support for an ENABLE_XOM build flag for global builds.
Bug: 77958880
Test: make -j ENABLE_XOM=true
Change-Id: Ia2ea981498dd12941aaf5ca807648ae37527e3ee
diff --git a/Android.bp b/Android.bp
index ef42c84..be9cf2a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -145,6 +145,7 @@
"cc/util.go",
"cc/vndk.go",
"cc/vndk_prebuilt.go",
+ "cc/xom.go",
"cc/cmakelists.go",
"cc/compdb.go",
diff --git a/android/config.go b/android/config.go
index 50c1413..0171cc0 100644
--- a/android/config.go
+++ b/android/config.go
@@ -626,6 +626,14 @@
}
}
+func (c *config) EnableXOM() bool {
+ if c.productVariables.EnableXOM == nil {
+ return false
+ } else {
+ return Bool(c.productVariables.EnableXOM)
+ }
+}
+
func (c *config) Android64() bool {
for _, t := range c.Targets[Android] {
if t.Arch.ArchType.Multilib == "lib64" {
@@ -863,6 +871,13 @@
return PrefixInList(path, *c.productVariables.CFIIncludePaths)
}
+func (c *config) XOMDisabledForPath(path string) bool {
+ if c.productVariables.XOMExcludePaths == nil {
+ return false
+ }
+ return PrefixInList(path, *c.productVariables.XOMExcludePaths)
+}
+
func (c *config) VendorConfig(name string) VendorConfig {
return vendorConfig(c.productVariables.VendorVars[name])
}
diff --git a/android/variable.go b/android/variable.go
index fbbde36..0b344f9 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -211,6 +211,9 @@
CFIExcludePaths *[]string `json:",omitempty"`
CFIIncludePaths *[]string `json:",omitempty"`
+ EnableXOM *bool `json:",omitempty"`
+ XOMExcludePaths *[]string `json:",omitempty"`
+
VendorPath *string `json:",omitempty"`
OdmPath *string `json:",omitempty"`
ProductPath *string `json:",omitempty"`
diff --git a/cc/cc.go b/cc/cc.go
index 5485ae3..3aaaf39 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -360,6 +360,7 @@
vndkdep *vndkdep
lto *lto
pgo *pgo
+ xom *xom
androidMkSharedLibDeps []string
@@ -417,6 +418,9 @@
if c.pgo != nil {
c.AddProperties(c.pgo.props()...)
}
+ if c.xom != nil {
+ c.AddProperties(c.xom.props()...)
+ }
for _, feature := range c.features {
c.AddProperties(feature.props()...)
}
@@ -658,6 +662,7 @@
module.vndkdep = &vndkdep{}
module.lto = <o{}
module.pgo = &pgo{}
+ module.xom = &xom{}
return module
}
@@ -774,6 +779,9 @@
if c.pgo != nil {
flags = c.pgo.flags(ctx, flags)
}
+ if c.xom != nil {
+ flags = c.xom.flags(ctx, flags)
+ }
for _, feature := range c.features {
flags = feature.flags(ctx, flags)
}
@@ -1641,6 +1649,7 @@
&VndkProperties{},
<OProperties{},
&PgoProperties{},
+ &XomProperties{},
&android.ProtoProperties{},
)
diff --git a/cc/xom.go b/cc/xom.go
new file mode 100644
index 0000000..f65fc24
--- /dev/null
+++ b/cc/xom.go
@@ -0,0 +1,75 @@
+// Copyright 2018 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 (
+ "android/soong/android"
+)
+
+type XomProperties struct {
+ Xom *bool
+}
+
+type xom struct {
+ Properties XomProperties
+}
+
+func (xom *xom) props() []interface{} {
+ return []interface{}{&xom.Properties}
+}
+
+func (xom *xom) begin(ctx BaseModuleContext) {}
+
+func (xom *xom) deps(ctx BaseModuleContext, deps Deps) Deps {
+ return deps
+}
+
+func (xom *xom) flags(ctx ModuleContext, flags Flags) Flags {
+ disableXom := false
+
+ if !ctx.Config().EnableXOM() || ctx.Config().XOMDisabledForPath(ctx.ModuleDir()) {
+ disableXom = true
+ }
+
+ if xom.Properties.Xom != nil && !*xom.Properties.Xom {
+ return flags
+ }
+
+ // If any static dependencies have XOM disabled, we should disable XOM in this module,
+ // the assumption being if it's been explicitly disabled then there's probably incompatible
+ // code in the library which may get pulled in.
+ if !ctx.static() && !disableXom {
+ ctx.VisitDirectDeps(func(m android.Module) {
+ cc, ok := m.(*Module)
+ if !ok || cc.xom == nil || !cc.static() {
+ return
+ }
+ if cc.xom.Properties.Xom != nil && !*cc.xom.Properties.Xom {
+ disableXom = true
+ return
+ }
+ })
+ }
+
+ // Enable execute-only if none of the dependencies disable it,
+ // also if it's explicitly set true (allows overriding dependencies disabling it).
+ if !disableXom || (xom.Properties.Xom != nil && *xom.Properties.Xom) {
+ if ctx.Arch().ArchType == android.Arm64 {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-execute-only")
+ }
+ }
+
+ return flags
+}