From 074ec480ef03c754e9abbda9617e94cdb7901a07 Mon Sep 17 00:00:00 2001 From: Ivan Lozano Date: Wed, 21 Nov 2018 08:59:37 -0800 Subject: [PATCH] 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 --- Android.bp | 1 + android/config.go | 15 +++++++++ android/variable.go | 3 ++ cc/cc.go | 9 ++++++ cc/xom.go | 75 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 cc/xom.go diff --git a/Android.bp b/Android.bp index ef42c84c4..be9cf2a05 100644 --- a/Android.bp +++ b/Android.bp @@ -145,6 +145,7 @@ bootstrap_go_package { "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 50c141385..0171cc069 100644 --- a/android/config.go +++ b/android/config.go @@ -626,6 +626,14 @@ func (c *config) EnableCFI() bool { } } +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 @@ func (c *config) CFIEnabledForPath(path string) bool { 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 fbbde36fd..0b344f996 100644 --- a/android/variable.go +++ b/android/variable.go @@ -211,6 +211,9 @@ type productVariables struct { 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 5485ae33b..3aaaf39d9 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -360,6 +360,7 @@ type Module struct { vndkdep *vndkdep lto *lto pgo *pgo + xom *xom androidMkSharedLibDeps []string @@ -417,6 +418,9 @@ func (c *Module) Init() android.Module { 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 @@ func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Mo module.vndkdep = &vndkdep{} module.lto = <o{} module.pgo = &pgo{} + module.xom = &xom{} return module } @@ -774,6 +779,9 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { 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 @@ func DefaultsFactory(props ...interface{}) android.Module { &VndkProperties{}, <OProperties{}, &PgoProperties{}, + &XomProperties{}, &android.ProtoProperties{}, ) diff --git a/cc/xom.go b/cc/xom.go new file mode 100644 index 000000000..f65fc2407 --- /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 +}