Merge "Enable SHT_RELR sections to encode relative relocations."
diff --git a/Android.bp b/Android.bp
index bdc34d0..5faefe6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -173,6 +173,7 @@
testSrcs: [
"cc/cc_test.go",
"cc/gen_test.go",
+ "cc/genrule_test.go",
"cc/library_test.go",
"cc/test_data_test.go",
"cc/util_test.go",
@@ -482,7 +483,7 @@
}
cc_genrule {
- name: "host_bionic_linker_script",
+ name: "host_bionic_linker_flags",
host_supported: true,
device_supported: false,
target: {
@@ -497,7 +498,7 @@
},
},
tools: ["extract_linker"],
- cmd: "$(location) -T $(out) $(in)",
+ cmd: "$(location) -f $(out) $(in)",
srcs: [":linker"],
- out: ["linker.script"],
+ out: ["linker.flags"],
}
diff --git a/android/androidmk.go b/android/androidmk.go
index 5df4a85..7030523 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -215,7 +215,7 @@
}
- if amod.Arch().ArchType != ctx.Config().Targets[amod.Os().Class][0].Arch.ArchType {
+ if amod.Arch().ArchType != ctx.Config().Targets[amod.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
diff --git a/android/arch.go b/android/arch.go
index 3378317..2543fca 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -194,7 +194,7 @@
NoOsType OsType
Linux = NewOsType("linux_glibc", Host, false)
Darwin = NewOsType("darwin", Host, false)
- LinuxBionic = NewOsType("linux_bionic", Host, true)
+ LinuxBionic = NewOsType("linux_bionic", Host, false)
Windows = NewOsType("windows", HostCross, true)
Android = NewOsType("android", Device, false)
@@ -325,37 +325,46 @@
return
}
- osClasses := base.OsClassSupported()
-
var moduleTargets []Target
moduleMultiTargets := make(map[int][]Target)
primaryModules := make(map[int]bool)
+ osClasses := base.OsClassSupported()
- for _, class := range osClasses {
- classTargets := mctx.Config().Targets[class]
- if len(classTargets) == 0 {
+ for _, os := range osTypeList {
+ supportedClass := false
+ for _, osClass := range osClasses {
+ if os.Class == osClass {
+ supportedClass = true
+ }
+ }
+ if !supportedClass {
+ continue
+ }
+
+ osTargets := mctx.Config().Targets[os]
+ if len(osTargets) == 0 {
continue
}
// only the primary arch in the recovery partition
- if module.InstallInRecovery() {
- classTargets = []Target{mctx.Config().Targets[Device][0]}
+ if os == Android && module.InstallInRecovery() {
+ osTargets = []Target{osTargets[0]}
}
prefer32 := false
if base.prefer32 != nil {
- prefer32 = base.prefer32(mctx, base, class)
+ prefer32 = base.prefer32(mctx, base, os.Class)
}
- multilib, extraMultilib := decodeMultilib(base, class)
- targets, err := decodeMultilibTargets(multilib, classTargets, prefer32)
+ multilib, extraMultilib := decodeMultilib(base, os.Class)
+ targets, err := decodeMultilibTargets(multilib, osTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
var multiTargets []Target
if extraMultilib != "" {
- multiTargets, err = decodeMultilibTargets(extraMultilib, classTargets, prefer32)
+ multiTargets, err = decodeMultilibTargets(extraMultilib, osTargets, prefer32)
if err != nil {
mctx.ModuleErrorf("%s", err.Error())
}
@@ -839,17 +848,17 @@
}
if (arch.ArchType == X86 && (hasArmAbi(arch) ||
- hasArmAndroidArch(ctx.Config().Targets[Device]))) ||
+ hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
(arch.ArchType == Arm &&
- hasX86AndroidArch(ctx.Config().Targets[Device])) {
+ hasX86AndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86"
prefix := "target.arm_on_x86"
a.appendProperties(ctx, genProps, targetProp, field, prefix)
}
if (arch.ArchType == X86_64 && (hasArmAbi(arch) ||
- hasArmAndroidArch(ctx.Config().Targets[Device]))) ||
+ hasArmAndroidArch(ctx.Config().Targets[Android]))) ||
(arch.ArchType == Arm &&
- hasX8664AndroidArch(ctx.Config().Targets[Device])) {
+ hasX8664AndroidArch(ctx.Config().Targets[Android])) {
field := "Arm_on_x86_64"
prefix := "target.arm_on_x86_64"
a.appendProperties(ctx, genProps, targetProp, field, prefix)
@@ -874,10 +883,10 @@
}
// Convert the arch product variables into a list of targets for each os class structs
-func decodeTargetProductVariables(config *config) (map[OsClass][]Target, error) {
+func decodeTargetProductVariables(config *config) (map[OsType][]Target, error) {
variables := config.productVariables
- targets := make(map[OsClass][]Target)
+ targets := make(map[OsType][]Target)
var targetErr error
addTarget := func(os OsType, archName string, archVariant, cpuVariant *string, abi *[]string) {
@@ -891,7 +900,7 @@
return
}
- targets[os.Class] = append(targets[os.Class],
+ targets[os] = append(targets[os],
Target{
Os: os,
Arch: arch,
@@ -938,7 +947,7 @@
variables.DeviceSecondaryArchVariant, variables.DeviceSecondaryCpuVariant,
variables.DeviceSecondaryAbi)
- deviceArches := targets[Device]
+ deviceArches := targets[Android]
if deviceArches[0].Arch.ArchType.Multilib == deviceArches[1].Arch.ArchType.Multilib {
deviceArches[1].Arch.Native = false
}
diff --git a/android/config.go b/android/config.go
index 5da1e0b..3b7b477 100644
--- a/android/config.go
+++ b/android/config.go
@@ -41,7 +41,6 @@
// config file. These will be included in the config struct.
type FileConfigurableOptions struct {
Mega_device *bool `json:",omitempty"`
- Ndk_abis *bool `json:",omitempty"`
Host_bionic *bool `json:",omitempty"`
}
@@ -90,7 +89,7 @@
ConfigFileName string
ProductVariablesFileName string
- Targets map[OsClass][]Target
+ Targets map[OsType][]Target
BuildOsVariant string
BuildOsCommonVariant string
@@ -230,18 +229,18 @@
testConfig := TestConfig(buildDir, env)
config := testConfig.config
- config.Targets = map[OsClass][]Target{
- Device: []Target{
+ config.Targets = map[OsType][]Target{
+ Android: []Target{
{Android, Arch{ArchType: Arm64, ArchVariant: "armv8-a", Native: true, Abi: []string{"arm64-v8a"}}},
{Android, Arch{ArchType: Arm, ArchVariant: "armv7-a-neon", Native: true, Abi: []string{"armeabi-v7a"}}},
},
- Host: []Target{
+ BuildOs: []Target{
{BuildOs, Arch{ArchType: X86_64}},
{BuildOs, Arch{ArchType: X86}},
},
}
- config.BuildOsVariant = config.Targets[Host][0].String()
+ config.BuildOsVariant = config.Targets[BuildOs][0].String()
return testConfig
}
@@ -299,21 +298,21 @@
var archConfig []archConfig
if Bool(config.Mega_device) {
archConfig = getMegaDeviceConfig()
- } else if Bool(config.Ndk_abis) {
+ } else if config.NdkAbis() {
archConfig = getNdkAbisConfig()
}
if archConfig != nil {
- deviceTargets, err := decodeArchSettings(archConfig)
+ androidTargets, err := decodeArchSettings(archConfig)
if err != nil {
return Config{}, err
}
- targets[Device] = deviceTargets
+ targets[Android] = androidTargets
}
config.Targets = targets
- config.BuildOsVariant = targets[Host][0].String()
- config.BuildOsCommonVariant = getCommonTargets(targets[Host])[0].String()
+ config.BuildOsVariant = targets[BuildOs][0].String()
+ config.BuildOsCommonVariant = getCommonTargets(targets[BuildOs])[0].String()
if err := config.fromEnv(); err != nil {
return Config{}, err
@@ -587,7 +586,7 @@
}
func (c *config) DevicePrimaryArchType() ArchType {
- return c.Targets[Device][0].Arch.ArchType
+ return c.Targets[Android][0].Arch.ArchType
}
func (c *config) SkipDeviceInstall() bool {
@@ -624,7 +623,7 @@
}
func (c *config) Android64() bool {
- for _, t := range c.Targets[Device] {
+ for _, t := range c.Targets[Android] {
if t.Arch.ArchType.Multilib == "lib64" {
return true
}
@@ -646,10 +645,6 @@
return c.targetOpenJDK9
}
-func (c *config) UseClangLld() bool {
- return Bool(c.productVariables.UseClangLld)
-}
-
func (c *config) ClangTidy() bool {
return Bool(c.productVariables.ClangTidy)
}
@@ -667,8 +662,8 @@
func (c *config) LibartImgDeviceBaseAddress() string {
archType := Common
- if len(c.Targets[Device]) > 0 {
- archType = c.Targets[Device][0].Arch.ArchType
+ if len(c.Targets[Android]) > 0 {
+ archType = c.Targets[Android][0].Arch.ArchType
}
switch archType {
default:
@@ -715,7 +710,7 @@
func (c *deviceConfig) Arches() []Arch {
var arches []Arch
- for _, target := range c.config.Targets[Device] {
+ for _, target := range c.config.Targets[Android] {
arches = append(arches, target.Arch)
}
return arches
@@ -866,6 +861,10 @@
return ok
}
+func (c *config) NdkAbis() bool {
+ return Bool(c.productVariables.Ndk_abis)
+}
+
func stringSlice(s *[]string) []string {
if s != nil {
return *s
diff --git a/android/module.go b/android/module.go
index 9d9d9a9..556c73d 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1071,10 +1071,10 @@
}
func (a *androidBaseContextImpl) PrimaryArch() bool {
- if len(a.config.Targets[a.target.Os.Class]) <= 1 {
+ if len(a.config.Targets[a.target.Os]) <= 1 {
return true
}
- return a.target.Arch.ArchType == a.config.Targets[a.target.Os.Class][0].Arch.ArchType
+ return a.target.Arch.ArchType == a.config.Targets[a.target.Os][0].Arch.ArchType
}
func (a *androidBaseContextImpl) AConfig() Config {
diff --git a/android/paths.go b/android/paths.go
index daaf857..b22e3c7 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -725,46 +725,6 @@
return PathForOutput(ctx, ".intermediates", path)
}
-// DistPath is a Path representing a file path rooted from the dist directory
-type DistPath struct {
- basePath
-}
-
-func (p DistPath) withRel(rel string) DistPath {
- p.basePath = p.basePath.withRel(rel)
- return p
-}
-
-var _ Path = DistPath{}
-
-// PathForDist joins the provided paths and returns a DistPath that is
-// validated to not escape the dist dir.
-// On error, it will return a usable, but invalid DistPath, and report a ModuleError.
-func PathForDist(ctx PathContext, pathComponents ...string) DistPath {
- path, err := validatePath(pathComponents...)
- if err != nil {
- reportPathError(ctx, err)
- }
- return DistPath{basePath{path, ctx.Config(), ""}}
-}
-
-func (p DistPath) writablePath() {}
-
-func (p DistPath) Valid() bool {
- return p.config.productVariables.DistDir != nil && *p.config.productVariables.DistDir != ""
-}
-
-func (p DistPath) String() string {
- if !p.Valid() {
- panic("Requesting an invalid path")
- }
- return filepath.Join(*p.config.productVariables.DistDir, p.path)
-}
-
-func (p DistPath) RelPathString() string {
- return p.path
-}
-
// ModuleSrcPath is a Path representing a file rooted from a module's local source dir
type ModuleSrcPath struct {
SourcePath
diff --git a/android/variable.go b/android/variable.go
index 5c4d491..2eb9900 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -201,8 +201,6 @@
ProductPath *string `json:",omitempty"`
ProductServicesPath *string `json:",omitempty"`
- UseClangLld *bool `json:",omitempty"`
-
ClangTidy *bool `json:",omitempty"`
TidyChecks *string `json:",omitempty"`
@@ -228,7 +226,6 @@
Product_is_iot *bool `json:",omitempty"`
DeviceKernelHeaders []string `json:",omitempty"`
- DistDir *string `json:",omitempty"`
ExtraVndkVersions []string `json:",omitempty"`
@@ -242,6 +239,8 @@
BoardPlatPrivateSepolicyDirs []string `json:",omitempty"`
VendorVars map[string]map[string]string `json:",omitempty"`
+
+ Ndk_abis *bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 619ac33..5390114 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -113,7 +113,7 @@
apexBundleName := mctx.Module().Name()
mctx.WalkDeps(func(child, parent android.Module) bool {
if am, ok := child.(android.ApexModule); ok && am.CanHaveApexVariants() {
- moduleName := am.Name()
+ moduleName := am.Name() + "-" + am.Target().String()
bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]
if !ok {
bundleNames = make(map[string]bool)
@@ -131,7 +131,7 @@
// Create apex variations if a module is included in APEX(s).
func apexMutator(mctx android.BottomUpMutatorContext) {
if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() {
- moduleName := am.Name()
+ moduleName := am.Name() + "-" + am.Target().String()
if bundleNames, ok := apexBundleNamesFor(mctx.Config())[moduleName]; ok {
variations := []string{"platform"}
for bn := range bundleNames {
diff --git a/cc/binary.go b/cc/binary.go
index 5fa501e..15db2ad 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -15,6 +15,8 @@
package cc
import (
+ "github.com/google/blueprint"
+
"android/soong/android"
)
@@ -154,7 +156,8 @@
}
if ctx.Os() == android.LinuxBionic && !binary.static() {
- deps.LinkerScript = "host_bionic_linker_script"
+ deps.DynamicLinker = "linker"
+ deps.LinkerFlagsFile = "host_bionic_linker_flags"
}
}
@@ -244,14 +247,23 @@
switch ctx.Os() {
case android.Android:
flags.DynamicLinker = "/system/bin/linker"
+ if flags.Toolchain.Is64Bit() {
+ flags.DynamicLinker += "64"
+ }
case android.LinuxBionic:
flags.DynamicLinker = ""
default:
ctx.ModuleErrorf("unknown dynamic linker")
}
- if flags.Toolchain.Is64Bit() {
- flags.DynamicLinker += "64"
- }
+ }
+
+ if ctx.Os() == android.LinuxBionic {
+ // Use the dlwrap entry point, but keep _start around so
+ // that it can be used by host_bionic_inject
+ flags.LdFlags = append(flags.LdFlags,
+ "-Wl,--entry=__dlwrap__start",
+ "-Wl,--undefined=_start",
+ )
}
}
@@ -262,7 +274,6 @@
"-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
)
-
}
} else {
if binary.static() {
@@ -288,13 +299,15 @@
sharedLibs := deps.SharedLibs
sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
- if deps.LinkerScript.Valid() {
- flags.LdFlags = append(flags.LdFlags, "-Wl,-T,"+deps.LinkerScript.String())
- linkerDeps = append(linkerDeps, deps.LinkerScript.Path())
+ if deps.LinkerFlagsFile.Valid() {
+ flags.LdFlags = append(flags.LdFlags, "$$(cat "+deps.LinkerFlagsFile.String()+")")
+ linkerDeps = append(linkerDeps, deps.LinkerFlagsFile.Path())
}
if flags.DynamicLinker != "" {
- flags.LdFlags = append(flags.LdFlags, " -Wl,-dynamic-linker,"+flags.DynamicLinker)
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
+ } else if ctx.toolchain().Bionic() && !binary.static() {
+ flags.LdFlags = append(flags.LdFlags, "-Wl,--no-dynamic-linker")
}
builderFlags := flagsToBuilderFlags(flags)
@@ -323,6 +336,17 @@
binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
}
+ if ctx.Os() == android.LinuxBionic && !binary.static() {
+ injectedOutputFile := outputFile
+ outputFile = android.PathForModuleOut(ctx, "prelinker", fileName)
+
+ if !deps.DynamicLinker.Valid() {
+ panic("Non-static host bionic modules must have a dynamic linker")
+ }
+
+ binary.injectHostBionicLinkerSymbols(ctx, outputFile, deps.DynamicLinker.Path(), injectedOutputFile)
+ }
+
linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
linkerDeps = append(linkerDeps, objs.tidyFiles...)
@@ -367,3 +391,26 @@
func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
return binary.toolPath
}
+
+func init() {
+ pctx.HostBinToolVariable("hostBionicSymbolsInjectCmd", "host_bionic_inject")
+}
+
+var injectHostBionicSymbols = pctx.AndroidStaticRule("injectHostBionicSymbols",
+ blueprint.RuleParams{
+ Command: "$hostBionicSymbolsInjectCmd -i $in -l $linker -o $out",
+ CommandDeps: []string{"$hostBionicSymbolsInjectCmd"},
+ }, "linker")
+
+func (binary *binaryDecorator) injectHostBionicLinkerSymbols(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: injectHostBionicSymbols,
+ Description: "inject host bionic symbols",
+ Input: in,
+ Implicit: linker,
+ Output: out,
+ Args: map[string]string{
+ "linker": linker.String(),
+ },
+ })
+}
diff --git a/cc/builder.go b/cc/builder.go
index d9a6cae..3d12538 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -191,11 +191,8 @@
func(ctx android.PackageRuleContext) blueprint.RuleParams {
// TODO(b/78139997): Add -check-all-apis back
commandStr := "($sAbiDiffer $allowFlags -lib $libName -arch $arch -o ${out} -new $in -old $referenceDump)"
- distAbiDiffDir := android.PathForDist(ctx, "abidiffs")
commandStr += "|| (echo ' ---- Please update abi references by running $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l ${libName} ----'"
- if distAbiDiffDir.Valid() {
- commandStr += " && (mkdir -p " + distAbiDiffDir.String() + " && cp ${out} " + distAbiDiffDir.String() + ")"
- }
+ commandStr += " && (mkdir -p $$DIST_DIR/abidiffs && cp ${out} $$DIST_DIR/abidiff/)"
commandStr += " && exit 1)"
return blueprint.RuleParams{
Command: commandStr,
diff --git a/cc/cc.go b/cc/cc.go
index 6320b9c..8b68489 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -83,7 +83,10 @@
ReexportGeneratedHeaders []string
CrtBegin, CrtEnd string
- LinkerScript string
+
+ // Used for host bionic
+ LinkerFlagsFile string
+ DynamicLinker string
}
type PathDeps struct {
@@ -108,7 +111,12 @@
// Paths to crt*.o files
CrtBegin, CrtEnd android.OptionalPath
- LinkerScript android.OptionalPath
+
+ // Path to the file container flags to use with the linker
+ LinkerFlagsFile android.OptionalPath
+
+ // Path to the dynamic linker binary
+ DynamicLinker android.OptionalPath
}
type Flags struct {
@@ -306,7 +314,8 @@
objDepTag = dependencyTag{name: "obj"}
crtBeginDepTag = dependencyTag{name: "crtbegin"}
crtEndDepTag = dependencyTag{name: "crtend"}
- linkerScriptDepTag = dependencyTag{name: "linker script"}
+ linkerFlagsDepTag = dependencyTag{name: "linker flags file"}
+ dynamicLinkerDepTag = dependencyTag{name: "dynamic linker"}
reuseObjTag = dependencyTag{name: "reuse objects"}
ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
@@ -1062,8 +1071,11 @@
if deps.CrtEnd != "" {
actx.AddVariationDependencies(nil, crtEndDepTag, deps.CrtEnd)
}
- if deps.LinkerScript != "" {
- actx.AddDependency(c, linkerScriptDepTag, deps.LinkerScript)
+ if deps.LinkerFlagsFile != "" {
+ actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile)
+ }
+ if deps.DynamicLinker != "" {
+ actx.AddDependency(c, dynamicLinkerDepTag, deps.DynamicLinker)
}
version := ctx.sdkVersion()
@@ -1257,13 +1269,13 @@
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
}
- case linkerScriptDepTag:
+ case linkerFlagsDepTag:
if genRule, ok := dep.(genrule.SourceFileGenerator); ok {
files := genRule.GeneratedSourceFiles()
if len(files) == 1 {
- depPaths.LinkerScript = android.OptionalPathForPath(files[0])
+ depPaths.LinkerFlagsFile = android.OptionalPathForPath(files[0])
} else if len(files) > 1 {
- ctx.ModuleErrorf("module %q can only generate a single file if used for a linker script", depName)
+ ctx.ModuleErrorf("module %q can only generate a single file if used for a linker flag file", depName)
}
} else {
ctx.ModuleErrorf("module %q is not a genrule", depName)
@@ -1358,6 +1370,8 @@
depPaths.CrtBegin = linkFile
case crtEndDepTag:
depPaths.CrtEnd = linkFile
+ case dynamicLinkerDepTag:
+ depPaths.DynamicLinker = linkFile
}
switch depTag {
diff --git a/cc/compiler.go b/cc/compiler.go
index 68d8593..5ac5d79 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -224,6 +224,10 @@
deps = protoDeps(ctx, deps, &compiler.Proto, Bool(compiler.Properties.Proto.Static))
}
+ if compiler.hasSrcExt(".sysprop") {
+ deps.SharedLibs = append(deps.SharedLibs, "libbase")
+ }
+
if Bool(compiler.Properties.Openmp) {
deps.StaticLibs = append(deps.StaticLibs, "libomp")
}
@@ -387,7 +391,7 @@
flags.GlobalFlags = append([]string{"${config.ClangExternalCflags}"}, flags.GlobalFlags...)
}
- if ctx.Device() {
+ if tc.Bionic() {
if Bool(compiler.Properties.Rtti) {
flags.CppFlags = append(flags.CppFlags, "-frtti")
} else {
@@ -489,6 +493,11 @@
flags = rsFlags(ctx, flags, &compiler.Properties)
}
+ if compiler.hasSrcExt(".sysprop") {
+ flags.GlobalFlags = append(flags.GlobalFlags,
+ "-I"+android.PathForModuleGen(ctx, "sysprop", "include").String())
+ }
+
if len(compiler.Properties.Srcs) > 0 {
module := ctx.ModuleDir() + "/Android.bp:" + ctx.ModuleName()
if inList("-Wno-error", flags.CFlags) || inList("-Wno-error", flags.CppFlags) {
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 6a63828..bcff775 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -25,6 +25,11 @@
arm64Cflags = []string{
// Help catch common 32/64-bit errors.
"-Werror=implicit-function-declaration",
+
+ // Prevent use of x18 register.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ "-ffixed-x18",
}
arm64ArchVariantCflags = map[string][]string{
diff --git a/cc/config/clang.go b/cc/config/clang.go
index b58223f..5c82604 100644
--- a/cc/config/clang.go
+++ b/cc/config/clang.go
@@ -174,6 +174,11 @@
// this new warning are fixed.
"-Wno-null-pointer-arithmetic",
+ // http://b/72330874 Disable -Wenum-compare until the instances detected by this new
+ // warning are fixed.
+ "-Wno-enum-compare",
+ "-Wno-enum-compare-switch",
+
// Disable c++98-specific warning since Android is not concerned with C++98
// compatibility.
"-Wno-c++98-compat-extra-semi",
@@ -191,11 +196,9 @@
"-Wno-dangling-field",
}, " "))
- // Extra cflags for projects under external/ directory to disable warnings that are infeasible
- // to fix in all the external projects and their upstream repos.
+ // Extra cflags for projects under external/ directory
pctx.StaticVariable("ClangExtraExternalCflags", strings.Join([]string{
- "-Wno-enum-compare",
- "-Wno-enum-compare-switch",
+ // TODO(yikong): Move -Wno flags here
}, " "))
}
diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go
index 8a12523..5fb88e6 100644
--- a/cc/config/x86_linux_bionic_host.go
+++ b/cc/config/x86_linux_bionic_host.go
@@ -139,6 +139,10 @@
return true
}
+func (toolchainLinuxBionic) LibclangRuntimeLibraryArch() string {
+ return "x86_64"
+}
+
var toolchainLinuxBionicSingleton Toolchain = &toolchainLinuxBionic{}
func linuxBionicToolchainFactory(arch android.Arch) Toolchain {
diff --git a/cc/gen.go b/cc/gen.go
index 487f662..29a2bb2 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -19,6 +19,8 @@
// functions.
import (
+ "path/filepath"
+
"github.com/google/blueprint"
"android/soong/android"
@@ -30,6 +32,7 @@
pctx.SourcePathVariable("yaccDataDir", "prebuilts/build-tools/common/bison")
pctx.HostBinToolVariable("aidlCmd", "aidl-cpp")
+ pctx.HostBinToolVariable("syspropCmd", "sysprop_cpp")
}
var (
@@ -55,6 +58,13 @@
},
"aidlFlags", "outDir")
+ sysprop = pctx.AndroidStaticRule("sysprop",
+ blueprint.RuleParams{
+ Command: "$syspropCmd --header-output-dir=$headerOutDir --source-output-dir=$srcOutDir --include-name=$includeName $in",
+ CommandDeps: []string{"$syspropCmd"},
+ },
+ "headerOutDir", "srcOutDir", "includeName")
+
windmc = pctx.AndroidStaticRule("windmc",
blueprint.RuleParams{
Command: "$windmcCmd -r$$(dirname $out) -h$$(dirname $out) $in",
@@ -82,7 +92,6 @@
}
func genAidl(ctx android.ModuleContext, aidlFile android.Path, outFile android.ModuleGenPath, aidlFlags string) android.Paths {
-
ctx.Build(pctx, android.BuildParams{
Rule: aidl,
Description: "aidl " + aidlFile.Rel(),
@@ -107,6 +116,26 @@
})
}
+func genSysprop(ctx android.ModuleContext, syspropFile android.Path) (android.Path, android.Path) {
+ headerFile := android.PathForModuleGen(ctx, "sysprop", "include", syspropFile.Rel()+".h")
+ cppFile := android.PathForModuleGen(ctx, "sysprop", syspropFile.Rel()+".cpp")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: sysprop,
+ Description: "sysprop " + syspropFile.Rel(),
+ Output: cppFile,
+ ImplicitOutput: headerFile,
+ Input: syspropFile,
+ Args: map[string]string{
+ "headerOutDir": filepath.Dir(headerFile.String()),
+ "srcOutDir": filepath.Dir(cppFile.String()),
+ "includeName": syspropFile.Rel() + ".h",
+ },
+ })
+
+ return cppFile, headerFile
+}
+
func genWinMsg(ctx android.ModuleContext, srcFile android.Path, flags builderFlags) (android.Path, android.Path) {
headerFile := android.GenPathWithExt(ctx, "windmc", srcFile, "h")
rcFile := android.GenPathWithExt(ctx, "windmc", srcFile, "rc")
@@ -169,6 +198,10 @@
rcFile, headerFile := genWinMsg(ctx, srcFile, buildFlags)
srcFiles[i] = rcFile
deps = append(deps, headerFile)
+ case ".sysprop":
+ cppFile, headerFile := genSysprop(ctx, srcFile)
+ srcFiles[i] = cppFile
+ deps = append(deps, headerFile)
}
}
diff --git a/cc/genrule_test.go b/cc/genrule_test.go
new file mode 100644
index 0000000..92024ac
--- /dev/null
+++ b/cc/genrule_test.go
@@ -0,0 +1,88 @@
+// 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 (
+ "reflect"
+ "testing"
+
+ "android/soong/android"
+)
+
+func testGenruleContext(config android.Config, bp string,
+ fs map[string][]byte) *android.TestContext {
+
+ ctx := android.NewTestArchContext()
+ ctx.RegisterModuleType("cc_genrule", android.ModuleFactoryAdaptor(genRuleFactory))
+ ctx.Register()
+
+ mockFS := map[string][]byte{
+ "Android.bp": []byte(bp),
+ "tool": nil,
+ "foo": nil,
+ "bar": nil,
+ }
+
+ for k, v := range fs {
+ mockFS[k] = v
+ }
+
+ ctx.MockFileSystem(mockFS)
+
+ return ctx
+}
+
+func TestArchGenruleCmd(t *testing.T) {
+ config := android.TestArchConfig(buildDir, nil)
+ bp := `
+ cc_genrule {
+ name: "gen",
+ tool_files: ["tool"],
+ cmd: "$(location tool) $(in) $(out)",
+ arch: {
+ arm: {
+ srcs: ["foo"],
+ out: ["out_arm"],
+ },
+ arm64: {
+ srcs: ["bar"],
+ out: ["out_arm64"],
+ },
+ },
+ }
+ `
+
+ ctx := testGenruleContext(config, bp, nil)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ if errs == nil {
+ _, errs = ctx.PrepareBuildActions(config)
+ }
+ if errs != nil {
+ t.Fatal(errs)
+ }
+
+ gen := ctx.ModuleForTests("gen", "android_arm_armv7-a-neon").Output("out_arm")
+ expected := []string{"foo"}
+ if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
+ t.Errorf(`want arm inputs %v, got %v`, expected, gen.Inputs.Strings())
+ }
+
+ gen = ctx.ModuleForTests("gen", "android_arm64_armv8-a").Output("out_arm64")
+ expected = []string{"bar"}
+ if !reflect.DeepEqual(expected, gen.Inputs.Strings()) {
+ t.Errorf(`want arm64 inputs %v, got %v`, expected, gen.Inputs.Strings())
+ }
+}
diff --git a/cc/library.go b/cc/library.go
index 9eb3f47..920292d 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -678,6 +678,14 @@
}
}
+ if library.baseCompiler.hasSrcExt(".sysprop") {
+ flags := []string{
+ "-I" + android.PathForModuleGen(ctx, "sysprop", "include").String(),
+ }
+ library.reexportFlags(flags)
+ library.reuseExportedFlags = append(library.reuseExportedFlags, flags...)
+ }
+
return out
}
diff --git a/cc/linker.go b/cc/linker.go
index 2e1828a..28f4747 100644
--- a/cc/linker.go
+++ b/cc/linker.go
@@ -289,7 +289,7 @@
if linker.Properties.Use_clang_lld != nil {
return Bool(linker.Properties.Use_clang_lld)
}
- return ctx.Config().UseClangLld()
+ return true
}
// ModuleContext extends BaseModuleContext
diff --git a/cc/lto.go b/cc/lto.go
index fd2a869..d9d2662 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -76,7 +76,7 @@
if lto.Properties.Use_clang_lld != nil {
return Bool(lto.Properties.Use_clang_lld)
}
- return ctx.Config().UseClangLld()
+ return true
}
func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags {
@@ -113,6 +113,13 @@
flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-inline-threshold=0")
flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-unroll-threshold=0")
}
+
+ if ctx.Arch().ArchType == android.Arm64 {
+ // Prevent use of x18 register on arm64.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
+ }
}
return flags
}
diff --git a/cc/makevars.go b/cc/makevars.go
index b590786..32674a9 100644
--- a/cc/makevars.go
+++ b/cc/makevars.go
@@ -172,13 +172,13 @@
sort.Strings(ndkMigratedLibs)
ctx.Strict("NDK_MIGRATED_LIBS", strings.Join(ndkMigratedLibs, " "))
- hostTargets := ctx.Config().Targets[android.Host]
+ hostTargets := ctx.Config().Targets[android.BuildOs]
makeVarsToolchain(ctx, "", hostTargets[0])
if len(hostTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", hostTargets[1])
}
- crossTargets := ctx.Config().Targets[android.HostCross]
+ crossTargets := ctx.Config().Targets[android.Windows]
if len(crossTargets) > 0 {
makeVarsToolchain(ctx, "", crossTargets[0])
if len(crossTargets) > 1 {
@@ -186,7 +186,7 @@
}
}
- deviceTargets := ctx.Config().Targets[android.Device]
+ deviceTargets := ctx.Config().Targets[android.Android]
makeVarsToolchain(ctx, "", deviceTargets[0])
if len(deviceTargets) > 1 {
makeVarsToolchain(ctx, "2ND_", deviceTargets[1])
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index 1cd4829..a7d6e04 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -134,7 +134,7 @@
// but keep them when doing regular platform build.
// Ndk_abis property is only set to true with build/soong/scripts/build-ndk-prebuilts.sh
// TODO: Revert this once MIPS is supported in NDK again.
- if Bool(ctx.AConfig().Ndk_abis) && strings.Contains(ctx.ModuleName(), "mips") {
+ if ctx.Config().NdkAbis() && strings.Contains(ctx.ModuleName(), "mips") {
return
}
@@ -278,11 +278,7 @@
module.AddProperties(&module.properties)
- // Host module rather than device module because device module install steps
- // do not get run when embedded in make. We're not any of the existing
- // module types that can be exposed via the Android.mk exporter, so just use
- // a host module.
- android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+ android.InitAndroidModule(module)
return module
}
@@ -362,11 +358,7 @@
module.AddProperties(&module.properties)
- // Host module rather than device module because device module install steps
- // do not get run when embedded in make. We're not any of the existing
- // module types that can be exposed via the Android.mk exporter, so just use
- // a host module.
- android.InitAndroidArchModule(module, android.HostSupportedNoCross, android.MultilibFirst)
+ android.InitAndroidModule(module)
return module
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 330a5e3..527ae33 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -471,6 +471,13 @@
diagSanitizers = append(diagSanitizers, "cfi")
}
+ if ctx.Arch().ArchType == android.Arm64 {
+ // Prevent use of x18 register on arm64.
+ // TODO(pcc): Remove this flag once we upgrade past LLVM r340889
+ // which does this by default on Android.
+ flags.LdFlags = append(flags.LdFlags, "-Wl,-plugin-opt,-mattr=+reserve-x18")
+ }
+
if ctx.staticBinary() {
_, flags.CFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.CFlags)
_, flags.LdFlags = removeFromList("-fsanitize-cfi-cross-dso", flags.LdFlags)
diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go
index 3f24ab2..ea0bf4e 100644
--- a/cmd/extract_linker/main.go
+++ b/cmd/extract_linker/main.go
@@ -13,7 +13,7 @@
// limitations under the License.
// This tool extracts ELF LOAD segments from our linker binary, and produces an
-// assembly file and linker script which will embed those segments as sections
+// assembly file and linker flags which will embed those segments as sections
// in another binary.
package main
@@ -26,38 +26,15 @@
"io/ioutil"
"log"
"os"
- "text/template"
+ "strings"
)
-var linkerScriptTemplate = template.Must(template.New("linker_script").Parse(`
-ENTRY(__dlwrap__start)
-SECTIONS {
- __dlwrap_original_start = _start;
- /DISCARD/ : { *(.interp) }
-
-{{range .}}
- . = {{ printf "0x%x" .Vaddr }};
- {{.Name}} : { KEEP(*({{.Name}})) }
-{{end}}
-
- .text : { *(.text .text.*) }
- .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
- .data : { *(.data .data.* .gnu.linkonce.d.*) }
- .bss : { *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) }
-}
-`))
-
-type LinkerSection struct {
- Name string
- Vaddr uint64
-}
-
func main() {
var asmPath string
- var scriptPath string
+ var flagsPath string
flag.StringVar(&asmPath, "s", "", "Path to save the assembly file")
- flag.StringVar(&scriptPath, "T", "", "Path to save the linker script")
+ flag.StringVar(&flagsPath, "f", "", "Path to save the linker flags")
flag.Parse()
f, err := os.Open(flag.Arg(0))
@@ -72,19 +49,21 @@
}
asm := &bytes.Buffer{}
-
- fmt.Fprintln(asm, ".globl __dlwrap_linker_entry")
- fmt.Fprintf(asm, ".set __dlwrap_linker_entry, 0x%x\n\n", ef.Entry)
-
baseLoadAddr := uint64(0x1000)
- sections := []LinkerSection{}
load := 0
+ linkFlags := []string{}
+
+ fmt.Fprintln(asm, ".globl __dlwrap_linker_offset")
+ fmt.Fprintf(asm, ".set __dlwrap_linker_offset, 0x%x\n", baseLoadAddr)
+
for _, prog := range ef.Progs {
if prog.Type != elf.PT_LOAD {
continue
}
sectionName := fmt.Sprintf(".linker.sect%d", load)
+ symName := fmt.Sprintf("__dlwrap_linker_sect%d", load)
+
flags := ""
if prog.Flags&elf.PF_W != 0 {
flags += "w"
@@ -94,10 +73,12 @@
}
fmt.Fprintf(asm, ".section %s, \"a%s\"\n", sectionName, flags)
- if load == 0 {
- fmt.Fprintln(asm, ".globl __dlwrap_linker_code_start")
- fmt.Fprintln(asm, "__dlwrap_linker_code_start:")
- }
+ fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName)
+
+ linkFlags = append(linkFlags,
+ fmt.Sprintf("-Wl,--undefined=%s", symName),
+ fmt.Sprintf("-Wl,--section-start=%s=0x%x",
+ sectionName, baseLoadAddr+prog.Vaddr))
buffer, _ := ioutil.ReadAll(prog.Open())
bytesToAsm(asm, buffer)
@@ -113,11 +94,6 @@
}
fmt.Fprintln(asm)
- sections = append(sections, LinkerSection{
- Name: sectionName,
- Vaddr: baseLoadAddr + prog.Vaddr,
- })
-
load += 1
}
@@ -127,13 +103,10 @@
}
}
- if scriptPath != "" {
- buf := &bytes.Buffer{}
- if err := linkerScriptTemplate.Execute(buf, sections); err != nil {
- log.Fatalf("Failed to create linker script: %v", err)
- }
- if err := ioutil.WriteFile(scriptPath, buf.Bytes(), 0777); err != nil {
- log.Fatalf("Unable to write %q: %v", scriptPath, err)
+ if flagsPath != "" {
+ flags := strings.Join(linkFlags, " ")
+ if err := ioutil.WriteFile(flagsPath, []byte(flags), 0777); err != nil {
+ log.Fatalf("Unable to write %q: %v", flagsPath, err)
}
}
}
diff --git a/cmd/symbol_inject/Android.bp b/cmd/host_bionic_inject/Android.bp
similarity index 63%
copy from cmd/symbol_inject/Android.bp
copy to cmd/host_bionic_inject/Android.bp
index a2ea12b..acce683 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/cmd/host_bionic_inject/Android.bp
@@ -13,20 +13,7 @@
// limitations under the License.
blueprint_go_binary {
- name: "symbol_inject",
- srcs: [
- "symbol_inject.go",
- "elf.go",
- "macho.go",
- "pe.go",
- ],
- testSrcs: [
- "elf_symboldata_test.go",
- "elf_test.go",
- "macho_symboldata_test.go",
- "macho_test.go",
- "pe_symboldata_test.go",
- "pe_test.go",
- "symbol_inject_test.go",
- ],
+ name: "host_bionic_inject",
+ deps: ["soong-symbol_inject"],
+ srcs: ["host_bionic_inject.go"],
}
diff --git a/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_inject/host_bionic_inject.go
new file mode 100644
index 0000000..0dabbba
--- /dev/null
+++ b/cmd/host_bionic_inject/host_bionic_inject.go
@@ -0,0 +1,174 @@
+// 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.
+
+// Verifies a host bionic executable with an embedded linker, then injects
+// the address of the _start function for the linker_wrapper to use.
+package main
+
+import (
+ "debug/elf"
+ "flag"
+ "fmt"
+ "io"
+ "os"
+
+ "android/soong/symbol_inject"
+)
+
+func main() {
+ var inputFile, linkerFile, outputFile string
+
+ flag.StringVar(&inputFile, "i", "", "Input file")
+ flag.StringVar(&linkerFile, "l", "", "Linker file")
+ flag.StringVar(&outputFile, "o", "", "Output file")
+ flag.Parse()
+
+ if inputFile == "" || linkerFile == "" || outputFile == "" || flag.NArg() != 0 {
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ r, err := os.Open(inputFile)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(2)
+ }
+ defer r.Close()
+
+ file, err := symbol_inject.OpenFile(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(3)
+ }
+
+ linker, err := elf.Open(linkerFile)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(4)
+ }
+
+ start_addr, err := parseElf(r, linker)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(5)
+ }
+
+ w, err := os.OpenFile(outputFile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(6)
+ }
+ defer w.Close()
+
+ err = symbol_inject.InjectUint64Symbol(file, w, "__dlwrap_original_start", start_addr)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(7)
+ }
+}
+
+// Check the ELF file, and return the address to the _start function
+func parseElf(r io.ReaderAt, linker *elf.File) (uint64, error) {
+ file, err := elf.NewFile(r)
+ if err != nil {
+ return 0, err
+ }
+
+ symbols, err := file.Symbols()
+ if err != nil {
+ return 0, err
+ }
+
+ for _, prog := range file.Progs {
+ if prog.Type == elf.PT_INTERP {
+ return 0, fmt.Errorf("File should not have a PT_INTERP header")
+ }
+ }
+
+ if dlwrap_start, err := findSymbol(symbols, "__dlwrap__start"); err != nil {
+ return 0, err
+ } else if dlwrap_start.Value != file.Entry {
+ return 0, fmt.Errorf("Expected file entry(0x%x) to point to __dlwrap_start(0x%x)",
+ file.Entry, dlwrap_start.Value)
+ }
+
+ err = checkLinker(file, linker, symbols)
+ if err != nil {
+ return 0, err
+ }
+
+ start, err := findSymbol(symbols, "_start")
+ if err != nil {
+ return 0, fmt.Errorf("Failed to find _start symbol")
+ }
+ return start.Value, nil
+}
+
+func findSymbol(symbols []elf.Symbol, name string) (elf.Symbol, error) {
+ for _, sym := range symbols {
+ if sym.Name == name {
+ return sym, nil
+ }
+ }
+ return elf.Symbol{}, fmt.Errorf("Failed to find symbol %q", name)
+}
+
+// Check that all of the PT_LOAD segments have been embedded properly
+func checkLinker(file, linker *elf.File, fileSyms []elf.Symbol) error {
+ dlwrap_linker_offset, err := findSymbol(fileSyms, "__dlwrap_linker_offset")
+ if err != nil {
+ return err
+ }
+
+ for i, lprog := range linker.Progs {
+ if lprog.Type != elf.PT_LOAD {
+ continue
+ }
+
+ found := false
+ for j, prog := range file.Progs {
+ if prog.Type != elf.PT_LOAD {
+ continue
+ }
+
+ if lprog.Vaddr+dlwrap_linker_offset.Value != prog.Vaddr {
+ continue
+ }
+ found = true
+
+ if lprog.Memsz != prog.Memsz {
+ return fmt.Errorf("Linker prog %d (0x%x) memsz (0x%x) does not match (0x%x)",
+ i, lprog.Vaddr, lprog.Memsz, prog.Memsz)
+ }
+
+ // The linker shouldn't be using BSS, since only one
+ // BSS section is supported per ELF file.
+ if prog.Memsz != prog.Filesz {
+ return fmt.Errorf("Embedded prog %d (0x%x) memsz (0x%x) does not match filesz (0x%x)",
+ j, prog.Vaddr, prog.Memsz, prog.Filesz)
+ }
+
+ if lprog.Flags != prog.Flags {
+ return fmt.Errorf("Linker prog %d (0x%x) flags (%s) do not match (%s)",
+ i, lprog.Vaddr, lprog.Flags, prog.Flags)
+ }
+ }
+ if !found {
+ return fmt.Errorf("Linker prog %d (0x%x) not found at offset 0x%x",
+ i, lprog.Vaddr, dlwrap_linker_offset.Value)
+ }
+ }
+
+ return nil
+}
diff --git a/genrule/genrule.go b/genrule/genrule.go
index 2824e49..e6c6efd 100644
--- a/genrule/genrule.go
+++ b/genrule/genrule.go
@@ -87,7 +87,7 @@
Export_include_dirs []string
// list of input files
- Srcs []string
+ Srcs []string `android:"arch_variant"`
}
type Module struct {
@@ -504,7 +504,7 @@
type genRuleProperties struct {
// names of the output files that will be generated
- Out []string
+ Out []string `android:"arch_variant"`
}
var Bool = proptools.Bool
diff --git a/genrule/genrule_test.go b/genrule/genrule_test.go
index 7e16ce1..a99fa18 100644
--- a/genrule/genrule_test.go
+++ b/genrule/genrule_test.go
@@ -27,7 +27,7 @@
func setUp() {
var err error
- buildDir, err = ioutil.TempDir("", "soong_java_test")
+ buildDir, err = ioutil.TempDir("", "genrule_test")
if err != nil {
panic(err)
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 063f2c1..fca5fc4 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -388,6 +388,7 @@
metalavaStubsFlags string
metalavaAnnotationsFlags string
+ metalavaInclusionAnnotationsFlags string
metalavaApiLevelsAnnotationsFlags string
metalavaApiToXmlFlags string
@@ -1382,7 +1383,6 @@
} else {
metalavaFlags += " --stubs " + android.PathForModuleOut(ctx, "stubsDir").String()
}
-
return metalavaFlags
}
@@ -1419,8 +1419,15 @@
}
})
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
- flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction "
+ flags += " --hide HiddenTypedefConstant --hide SuperfluousPrefix --hide AnnotationExtraction"
}
+
+ return flags
+}
+
+func (d *Droidstubs) collectInclusionAnnotationsFlags(ctx android.ModuleContext,
+ implicits *android.Paths, implicitOutputs *android.WritablePaths) string {
+ var flags string
ctx.VisitDirectDepsWithTag(metalavaMergeInclusionAnnotationsDirTag, func(m android.Module) {
if t, ok := m.(*ExportedDroiddocDir); ok {
*implicits = append(*implicits, t.deps...)
@@ -1599,6 +1606,7 @@
flags.metalavaStubsFlags = d.collectStubsFlags(ctx, &implicitOutputs)
flags.metalavaAnnotationsFlags = d.collectAnnotationsFlags(ctx, &implicits, &implicitOutputs)
+ flags.metalavaInclusionAnnotationsFlags = d.collectInclusionAnnotationsFlags(ctx, &implicits, &implicitOutputs)
flags.metalavaApiLevelsAnnotationsFlags = d.collectAPILevelsAnnotationsFlags(ctx, &implicits, &implicitOutputs)
flags.metalavaApiToXmlFlags = d.collectApiToXmlFlags(ctx, &implicits, &implicitOutputs)
@@ -1610,7 +1618,7 @@
}
d.transformMetalava(ctx, implicits, implicitOutputs, javaVersion,
flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs,
- flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+
+ flags.metalavaStubsFlags+flags.metalavaAnnotationsFlags+flags.metalavaInclusionAnnotationsFlags+
flags.metalavaApiLevelsAnnotationsFlags+flags.metalavaApiToXmlFlags+" "+d.Javadoc.args)
if apiCheckEnabled(d.properties.Check_api.Current, "current") &&
@@ -1621,8 +1629,9 @@
"check_api.current_removed_api_file")
d.checkCurrentApiTimestamp = android.PathForModuleOut(ctx, "check_current_api.timestamp")
- opts := d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
- " --check-compatibility:removed:current " + removedApiFile.String() + " "
+ opts := " " + d.Javadoc.args + " --check-compatibility:api:current " + apiFile.String() +
+ " --check-compatibility:removed:current " + removedApiFile.String() +
+ flags.metalavaInclusionAnnotationsFlags
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
@@ -1651,8 +1660,9 @@
"check_api.last_released.removed_api_file")
d.checkLastReleasedApiTimestamp = android.PathForModuleOut(ctx, "check_last_released_api.timestamp")
- opts := d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
- " --check-compatibility:removed:released " + removedApiFile.String() + " "
+ opts := " " + d.Javadoc.args + " --check-compatibility:api:released " + apiFile.String() +
+ flags.metalavaInclusionAnnotationsFlags + " --check-compatibility:removed:released " +
+ removedApiFile.String() + " "
d.transformCheckApi(ctx, apiFile, removedApiFile, metalavaCheckApiImplicits,
javaVersion, flags.bootClasspathArgs, flags.classpathArgs, flags.sourcepathArgs, opts,
diff --git a/java/gen.go b/java/gen.go
index a993829..993e6d1 100644
--- a/java/gen.go
+++ b/java/gen.go
@@ -26,6 +26,7 @@
func init() {
pctx.HostBinToolVariable("aidlCmd", "aidl")
+ pctx.HostBinToolVariable("syspropCmd", "sysprop_java")
pctx.SourcePathVariable("logtagsCmd", "build/tools/java-event-log-tags.py")
pctx.SourcePathVariable("mergeLogtagsCmd", "build/tools/merge-event-log-tags.py")
}
@@ -49,6 +50,17 @@
Command: "$mergeLogtagsCmd -o $out $in",
CommandDeps: []string{"$mergeLogtagsCmd"},
})
+
+ sysprop = pctx.AndroidStaticRule("sysprop",
+ blueprint.RuleParams{
+ Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` +
+ `$syspropCmd --java-output-dir $out.tmp $in && ` +
+ `${config.SoongZipCmd} -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`,
+ CommandDeps: []string{
+ "$syspropCmd",
+ "${config.SoongZipCmd}",
+ },
+ })
)
func genAidl(ctx android.ModuleContext, aidlFile android.Path, aidlFlags string) android.Path {
@@ -82,6 +94,19 @@
return javaFile
}
+func genSysprop(ctx android.ModuleContext, syspropFile android.Path) android.Path {
+ srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar")
+
+ ctx.Build(pctx, android.BuildParams{
+ Rule: sysprop,
+ Description: "sysprop_java " + syspropFile.Rel(),
+ Output: srcJarFile,
+ Input: syspropFile,
+ })
+
+ return srcJarFile
+}
+
func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
flags javaBuilderFlags) android.Paths {
@@ -99,6 +124,9 @@
case ".proto":
srcJarFile := genProto(ctx, srcFile, flags)
outSrcFiles = append(outSrcFiles, srcJarFile)
+ case ".sysprop":
+ srcJarFile := genSysprop(ctx, srcFile)
+ outSrcFiles = append(outSrcFiles, srcJarFile)
default:
outSrcFiles = append(outSrcFiles, srcFile)
}
diff --git a/java/java.go b/java/java.go
index d7068c6..f651884 100644
--- a/java/java.go
+++ b/java/java.go
@@ -725,27 +725,34 @@
javaPlatform
)
-func getLinkType(m *Module, name string) linkType {
+func getLinkType(m *Module, name string) (ret linkType, stubs bool) {
ver := m.sdkVersion()
- noStdLibs := Bool(m.properties.No_standard_libs)
switch {
- case name == "core.current.stubs" || ver == "core_current" ||
- name == "core.platform.api.stubs" || ver == "core_platform_current" ||
- noStdLibs || name == "stub-annotations" || name == "private-stub-annotations-jar":
- return javaCore
- case name == "android_system_stubs_current" || strings.HasPrefix(ver, "system_"):
- return javaSystem
- case name == "android_test_stubs_current" || strings.HasPrefix(ver, "test_"):
- return javaPlatform
- case name == "android_stubs_current" || ver == "current":
- return javaSdk
+ case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
+ name == "stub-annotations" || name == "private-stub-annotations-jar" ||
+ name == "core-lambda-stubs":
+ return javaCore, true
+ case ver == "core_current" || ver == "core_platform_current":
+ return javaCore, false
+ case name == "android_system_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "system_"):
+ return javaSystem, false
+ case name == "android_test_stubs_current":
+ return javaSystem, true
+ case strings.HasPrefix(ver, "test_"):
+ return javaPlatform, false
+ case name == "android_stubs_current":
+ return javaSdk, true
+ case ver == "current":
+ return javaSdk, false
case ver == "":
- return javaPlatform
+ return javaPlatform, false
default:
if _, err := strconv.Atoi(ver); err != nil {
panic(fmt.Errorf("expected sdk_version to be a number, got %q", ver))
}
- return javaSdk
+ return javaSdk, false
}
}
@@ -754,8 +761,11 @@
return
}
- myLinkType := getLinkType(from, ctx.ModuleName())
- otherLinkType := getLinkType(&to.Module, ctx.OtherModuleName(to))
+ myLinkType, stubs := getLinkType(from, ctx.ModuleName())
+ if stubs {
+ return
+ }
+ otherLinkType, _ := getLinkType(&to.Module, ctx.OtherModuleName(to))
commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source."
switch myLinkType {
@@ -860,7 +870,8 @@
case SdkLibraryDependency:
switch tag {
case libTag:
- deps.classpath = append(deps.classpath, dep.HeaderJars(getLinkType(j, ctx.ModuleName()))...)
+ linkType, _ := getLinkType(j, ctx.ModuleName())
+ deps.classpath = append(deps.classpath, dep.HeaderJars(linkType)...)
// names of sdk libs that are directly depended are exported
j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
default:
diff --git a/scripts/build-ndk-prebuilts.sh b/scripts/build-ndk-prebuilts.sh
index 7f6e2c9..0143d1e 100755
--- a/scripts/build-ndk-prebuilts.sh
+++ b/scripts/build-ndk-prebuilts.sh
@@ -34,11 +34,6 @@
SOONG_NDK_OUT=${OUT_DIR}/soong/ndk
rm -rf ${SOONG_OUT}
mkdir -p ${SOONG_OUT}
-cat > ${SOONG_OUT}/soong.config << EOF
-{
- "Ndk_abis": true
-}
-EOF
# We only really need to set some of these variables, but soong won't merge this
# with the defaults, so we need to write out all the defaults with our values
@@ -63,7 +58,9 @@
],
"HostArch": "x86_64",
"Malloc_not_svelte": false,
- "Safestack": false
+ "Safestack": false,
+
+ "Ndk_abis": true
}
EOF
m --skip-make ${SOONG_OUT}/ndk.timestamp
diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py
index 9256cb2..07925df 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -61,6 +61,9 @@
help='specify additional <uses-library> tag to add. android:requred is set to false')
parser.add_argument('--uses-non-sdk-api', dest='uses_non_sdk_api', action='store_true',
help='manifest is for a package built against the platform')
+ parser.add_argument('--prefer-integrity', type=bool, dest='prefer_integrity',
+ help=('specify if the app prefers strict integrity. Should not be conflict if ' +
+ 'already declared in the manifest.'))
parser.add_argument('input', help='input AndroidManifest.xml file')
parser.add_argument('output', help='output AndroidManifest.xml file')
return parser.parse_args()
@@ -269,6 +272,28 @@
application.setAttributeNode(attr)
+def add_prefer_integrity(doc):
+ manifest = parse_manifest(doc)
+ elems = get_children_with_tag(manifest, 'application')
+ application = elems[0] if len(elems) == 1 else None
+ if len(elems) > 1:
+ raise RuntimeError('found multiple <application> tags')
+ elif not elems:
+ application = doc.createElement('application')
+ indent = get_indent(manifest.firstChild, 1)
+ first = manifest.firstChild
+ manifest.insertBefore(doc.createTextNode(indent), first)
+ manifest.insertBefore(application, first)
+
+ attr = application.getAttributeNodeNS(android_ns, 'preferIntegrity')
+ if attr is None:
+ attr = doc.createAttributeNS(android_ns, 'android:preferIntegrity')
+ attr.value = 'true'
+ application.setAttributeNode(attr)
+ elif attr.value != 'true':
+ raise RuntimeError('existing attribute mismatches the option of --prefer-integrity')
+
+
def write_xml(f, doc):
f.write('<?xml version="1.0" encoding="utf-8"?>\n')
for node in doc.childNodes:
@@ -296,6 +321,9 @@
if args.uses_non_sdk_api:
add_uses_non_sdk_api(doc)
+ if args.prefer_integrity:
+ add_prefer_integrity(doc)
+
with open(args.output, 'wb') as f:
write_xml(f, doc)
diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py
index d1d401a..a621445 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -346,5 +346,40 @@
self.assertEqual(output, expected)
+class PreferIntegrityTest(unittest.TestCase):
+ """Unit tests for add_prefer_integrity function."""
+
+ def run_test(self, input_manifest):
+ doc = minidom.parseString(input_manifest)
+ manifest_fixer.add_prefer_integrity(doc)
+ output = StringIO.StringIO()
+ manifest_fixer.write_xml(output, doc)
+ return output.getvalue()
+
+ manifest_tmpl = (
+ '<?xml version="1.0" encoding="utf-8"?>\n'
+ '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n'
+ ' <application%s/>\n'
+ '</manifest>\n')
+
+ def prefer_integrity(self, value):
+ return ' android:preferIntegrity="%s"' % value
+
+ def test_manifest_with_undeclared_preference(self):
+ manifest_input = self.manifest_tmpl % ''
+ expected = self.manifest_tmpl % self.prefer_integrity('true')
+ output = self.run_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_manifest_with_prefer_integrity(self):
+ manifest_input = self.manifest_tmpl % self.prefer_integrity('true')
+ expected = manifest_input
+ output = self.run_test(manifest_input)
+ self.assertEqual(output, expected)
+
+ def test_manifest_with_not_prefer_integrity(self):
+ manifest_input = self.manifest_tmpl % self.prefer_integrity('false')
+ self.assertRaises(RuntimeError, self.run_test, manifest_input)
+
if __name__ == '__main__':
unittest.main()
diff --git a/cmd/symbol_inject/Android.bp b/symbol_inject/Android.bp
similarity index 90%
rename from cmd/symbol_inject/Android.bp
rename to symbol_inject/Android.bp
index a2ea12b..8308043 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/symbol_inject/Android.bp
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-blueprint_go_binary {
- name: "symbol_inject",
+bootstrap_go_package {
+ name: "soong-symbol_inject",
+ pkgPath: "android/soong/symbol_inject",
srcs: [
"symbol_inject.go",
"elf.go",
diff --git a/cmd/symbol_inject/Android.bp b/symbol_inject/cmd/Android.bp
similarity index 71%
copy from cmd/symbol_inject/Android.bp
copy to symbol_inject/cmd/Android.bp
index a2ea12b..ee2f259 100644
--- a/cmd/symbol_inject/Android.bp
+++ b/symbol_inject/cmd/Android.bp
@@ -14,19 +14,8 @@
blueprint_go_binary {
name: "symbol_inject",
+ deps: ["soong-symbol_inject"],
srcs: [
"symbol_inject.go",
- "elf.go",
- "macho.go",
- "pe.go",
- ],
- testSrcs: [
- "elf_symboldata_test.go",
- "elf_test.go",
- "macho_symboldata_test.go",
- "macho_test.go",
- "pe_symboldata_test.go",
- "pe_test.go",
- "symbol_inject_test.go",
],
}
diff --git a/symbol_inject/cmd/symbol_inject.go b/symbol_inject/cmd/symbol_inject.go
new file mode 100644
index 0000000..1397b37
--- /dev/null
+++ b/symbol_inject/cmd/symbol_inject.go
@@ -0,0 +1,97 @@
+// 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 main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+
+ "android/soong/symbol_inject"
+)
+
+var (
+ input = flag.String("i", "", "input file")
+ output = flag.String("o", "", "output file")
+ symbol = flag.String("s", "", "symbol to inject into")
+ from = flag.String("from", "", "optional existing value of the symbol for verification")
+ value = flag.String("v", "", "value to inject into symbol")
+
+ dump = flag.Bool("dump", false, "dump the symbol table for copying into a test")
+)
+
+func main() {
+ flag.Parse()
+
+ usageError := func(s string) {
+ fmt.Fprintln(os.Stderr, s)
+ flag.Usage()
+ os.Exit(1)
+ }
+
+ if *input == "" {
+ usageError("-i is required")
+ }
+
+ if !*dump {
+ if *output == "" {
+ usageError("-o is required")
+ }
+
+ if *symbol == "" {
+ usageError("-s is required")
+ }
+
+ if *value == "" {
+ usageError("-v is required")
+ }
+ }
+
+ r, err := os.Open(*input)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(2)
+ }
+ defer r.Close()
+
+ if *dump {
+ err := symbol_inject.DumpSymbols(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(6)
+ }
+ return
+ }
+
+ w, err := os.OpenFile(*output, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(3)
+ }
+ defer w.Close()
+
+ file, err := symbol_inject.OpenFile(r)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Exit(4)
+ }
+
+ err = symbol_inject.InjectStringSymbol(file, w, *symbol, *value, *from)
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err.Error())
+ os.Remove(*output)
+ os.Exit(5)
+ }
+}
diff --git a/cmd/symbol_inject/elf.go b/symbol_inject/elf.go
similarity index 99%
rename from cmd/symbol_inject/elf.go
rename to symbol_inject/elf.go
index d94877d..8742cbd 100644
--- a/cmd/symbol_inject/elf.go
+++ b/symbol_inject/elf.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/elf"
diff --git a/cmd/symbol_inject/elf_symboldata_test.go b/symbol_inject/elf_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/elf_symboldata_test.go
rename to symbol_inject/elf_symboldata_test.go
index 9ba7153..b2f1148 100644
--- a/cmd/symbol_inject/elf_symboldata_test.go
+++ b/symbol_inject/elf_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import "debug/elf"
diff --git a/cmd/symbol_inject/elf_test.go b/symbol_inject/elf_test.go
similarity index 98%
rename from cmd/symbol_inject/elf_test.go
rename to symbol_inject/elf_test.go
index 30b46a5..aceee44 100644
--- a/cmd/symbol_inject/elf_test.go
+++ b/symbol_inject/elf_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"strconv"
diff --git a/cmd/symbol_inject/macho.go b/symbol_inject/macho.go
similarity index 98%
rename from cmd/symbol_inject/macho.go
rename to symbol_inject/macho.go
index be49f8b..6ee3f4f 100644
--- a/cmd/symbol_inject/macho.go
+++ b/symbol_inject/macho.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/macho_symboldata_test.go b/symbol_inject/macho_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/macho_symboldata_test.go
rename to symbol_inject/macho_symboldata_test.go
index 3100a81..7336a27 100644
--- a/cmd/symbol_inject/macho_symboldata_test.go
+++ b/symbol_inject/macho_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/macho_test.go b/symbol_inject/macho_test.go
similarity index 98%
rename from cmd/symbol_inject/macho_test.go
rename to symbol_inject/macho_test.go
index 7acab23..50df131 100644
--- a/cmd/symbol_inject/macho_test.go
+++ b/symbol_inject/macho_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/macho"
diff --git a/cmd/symbol_inject/pe.go b/symbol_inject/pe.go
similarity index 98%
rename from cmd/symbol_inject/pe.go
rename to symbol_inject/pe.go
index 12f35ee..58cf91a 100644
--- a/cmd/symbol_inject/pe.go
+++ b/symbol_inject/pe.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/pe_symboldata_test.go b/symbol_inject/pe_symboldata_test.go
similarity index 99%
rename from cmd/symbol_inject/pe_symboldata_test.go
rename to symbol_inject/pe_symboldata_test.go
index edc1c97..5c0fd70 100644
--- a/cmd/symbol_inject/pe_symboldata_test.go
+++ b/symbol_inject/pe_symboldata_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/pe_test.go b/symbol_inject/pe_test.go
similarity index 99%
rename from cmd/symbol_inject/pe_test.go
rename to symbol_inject/pe_test.go
index 21a0bc4..df7bac3 100644
--- a/cmd/symbol_inject/pe_test.go
+++ b/symbol_inject/pe_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"debug/pe"
diff --git a/cmd/symbol_inject/symbol_inject.go b/symbol_inject/symbol_inject.go
similarity index 70%
rename from cmd/symbol_inject/symbol_inject.go
rename to symbol_inject/symbol_inject.go
index d0f01c5..2a3d67e 100644
--- a/cmd/symbol_inject/symbol_inject.go
+++ b/symbol_inject/symbol_inject.go
@@ -12,25 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"bytes"
- "flag"
+ "encoding/binary"
"fmt"
"io"
"math"
- "os"
-)
-
-var (
- input = flag.String("i", "", "input file")
- output = flag.String("o", "", "output file")
- symbol = flag.String("s", "", "symbol to inject into")
- from = flag.String("from", "", "optional existing value of the symbol for verification")
- value = flag.String("v", "", "value to inject into symbol")
-
- dump = flag.Bool("dump", false, "dump the symbol table for copying into a test")
)
var maxUint64 uint64 = math.MaxUint64
@@ -39,71 +28,7 @@
error
}
-func main() {
- flag.Parse()
-
- usageError := func(s string) {
- fmt.Fprintln(os.Stderr, s)
- flag.Usage()
- os.Exit(1)
- }
-
- if *input == "" {
- usageError("-i is required")
- }
-
- if !*dump {
- if *output == "" {
- usageError("-o is required")
- }
-
- if *symbol == "" {
- usageError("-s is required")
- }
-
- if *value == "" {
- usageError("-v is required")
- }
- }
-
- r, err := os.Open(*input)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(2)
- }
- defer r.Close()
-
- if *dump {
- err := dumpSymbols(r)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(6)
- }
- return
- }
-
- w, err := os.OpenFile(*output, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0777)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(3)
- }
- defer w.Close()
-
- file, err := openFile(r)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Exit(4)
- }
-
- err = injectSymbol(file, w, *symbol, *value, *from)
- if err != nil {
- fmt.Fprintln(os.Stderr, err.Error())
- os.Remove(*output)
- os.Exit(5)
- }
-}
-
-func openFile(r io.ReaderAt) (*File, error) {
+func OpenFile(r io.ReaderAt) (*File, error) {
file, err := elfSymbolsFromFile(r)
if elfError, ok := err.(cantParseError); ok {
// Try as a mach-o file
@@ -126,7 +51,7 @@
return file, err
}
-func injectSymbol(file *File, w io.Writer, symbol, value, from string) error {
+func InjectStringSymbol(file *File, w io.Writer, symbol, value, from string) error {
offset, size, err := findSymbol(file, symbol)
if err != nil {
return err
@@ -151,13 +76,29 @@
}
}
- return copyAndInject(file.r, w, offset, size, value)
-}
-
-func copyAndInject(r io.ReaderAt, w io.Writer, offset, size uint64, value string) (err error) {
buf := make([]byte, size)
copy(buf, value)
+ return copyAndInject(file.r, w, offset, buf)
+}
+
+func InjectUint64Symbol(file *File, w io.Writer, symbol string, value uint64) error {
+ offset, size, err := findSymbol(file, symbol)
+ if err != nil {
+ return err
+ }
+
+ if size != 8 {
+ return fmt.Errorf("symbol %q is not a uint64, it is %d bytes long", symbol, size)
+ }
+
+ buf := make([]byte, 8)
+ binary.LittleEndian.PutUint64(buf, value)
+
+ return copyAndInject(file.r, w, offset, buf)
+}
+
+func copyAndInject(r io.ReaderAt, w io.Writer, offset uint64, buf []byte) (err error) {
// Copy the first bytes up to the symbol offset
_, err = io.Copy(w, io.NewSectionReader(r, 0, int64(offset)))
@@ -167,7 +108,7 @@
}
// Write the remainder of the file
- pos := int64(offset + size)
+ pos := int64(offset) + int64(len(buf))
if err == nil {
_, err = io.Copy(w, io.NewSectionReader(r, pos, 1<<63-1-pos))
}
@@ -239,7 +180,7 @@
Size uint64
}
-func dumpSymbols(r io.ReaderAt) error {
+func DumpSymbols(r io.ReaderAt) error {
err := dumpElfSymbols(r)
if elfError, ok := err.(cantParseError); ok {
// Try as a mach-o file
diff --git a/cmd/symbol_inject/symbol_inject_test.go b/symbol_inject/symbol_inject_test.go
similarity index 77%
rename from cmd/symbol_inject/symbol_inject_test.go
rename to symbol_inject/symbol_inject_test.go
index dbee39a..6607e65 100644
--- a/cmd/symbol_inject/symbol_inject_test.go
+++ b/symbol_inject/symbol_inject_test.go
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package main
+package symbol_inject
import (
"bytes"
@@ -23,32 +23,23 @@
func TestCopyAndInject(t *testing.T) {
s := "abcdefghijklmnopqrstuvwxyz"
testCases := []struct {
- offset, size uint64
- value string
- expected string
+ offset uint64
+ buf string
+ expected string
}{
{
offset: 0,
- size: 1,
- value: "A",
+ buf: "A",
expected: "Abcdefghijklmnopqrstuvwxyz",
},
{
offset: 1,
- size: 1,
- value: "B",
- expected: "aBcdefghijklmnopqrstuvwxyz",
- },
- {
- offset: 1,
- size: 1,
- value: "BCD",
+ buf: "B",
expected: "aBcdefghijklmnopqrstuvwxyz",
},
{
offset: 25,
- size: 1,
- value: "Z",
+ buf: "Z",
expected: "abcdefghijklmnopqrstuvwxyZ",
},
}
@@ -57,7 +48,7 @@
t.Run(strconv.Itoa(i), func(t *testing.T) {
in := bytes.NewReader([]byte(s))
out := &bytes.Buffer{}
- copyAndInject(in, out, testCase.offset, testCase.size, testCase.value)
+ copyAndInject(in, out, testCase.offset, []byte(testCase.buf))
if out.String() != testCase.expected {
t.Errorf("expected %s, got %s", testCase.expected, out.String())
diff --git a/ui/build/build.go b/ui/build/build.go
index 377481b..c902a0f 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -40,9 +40,10 @@
pool local_pool
depth = {{.Parallel}}
build _kati_always_build_: phony
-{{if .HasKatiSuffix}}include {{.KatiBuildNinjaFile}}
+{{if .HasKatiSuffix}}subninja {{.KatiBuildNinjaFile}}
+subninja {{.KatiPackageNinjaFile}}
{{end -}}
-include {{.SoongNinjaFile}}
+subninja {{.SoongNinjaFile}}
`))
func createCombinedBuildNinjaFile(ctx Context, config Config) {
@@ -180,6 +181,7 @@
genKatiSuffix(ctx, config)
runKatiCleanSpec(ctx, config)
runKatiBuild(ctx, config)
+ runKatiPackage(ctx, config)
ioutil.WriteFile(config.LastKatiSuffixFile(), []byte(config.KatiSuffix()), 0777)
} else {
diff --git a/ui/build/config.go b/ui/build/config.go
index d65d97f..840f505 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -34,6 +34,7 @@
arguments []string
goma bool
environ *Environment
+ distDir string
// From the arguments
parallel int
@@ -86,8 +87,11 @@
ret.environ.Set("OUT_DIR", outDir)
}
- // Make sure DIST_DIR is set appropriately
- ret.environ.Set("DIST_DIR", ret.DistDir())
+ if distDir, ok := ret.environ.Get("DIST_DIR"); ok {
+ ret.distDir = filepath.Clean(distDir)
+ } else {
+ ret.distDir = filepath.Join(ret.OutDir(), "dist")
+ }
ret.environ.Unset(
// We're already using it
@@ -110,6 +114,9 @@
// We handle this above
"OUT_DIR_COMMON_BASE",
+ // This is handled above too, and set for individual commands later
+ "DIST_DIR",
+
// Variables that have caused problems in the past
"CDPATH",
"DISPLAY",
@@ -251,10 +258,10 @@
}
} else if k, v, ok := decodeKeyValue(arg); ok && len(k) > 0 {
c.environ.Set(k, v)
+ } else if arg == "dist" {
+ c.dist = true
} else {
- if arg == "dist" {
- c.dist = true
- } else if arg == "checkbuild" {
+ if arg == "checkbuild" {
c.checkbuild = true
}
c.arguments = append(c.arguments, arg)
@@ -378,10 +385,7 @@
}
func (c *configImpl) DistDir() string {
- if distDir, ok := c.environ.Get("DIST_DIR"); ok {
- return filepath.Clean(distDir)
- }
- return filepath.Join(c.OutDir(), "dist")
+ return c.distDir
}
func (c *configImpl) NinjaArgs() []string {
@@ -508,6 +512,10 @@
return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiBuildSuffix+".ninja")
}
+func (c *configImpl) KatiPackageNinjaFile() string {
+ return filepath.Join(c.OutDir(), "build"+c.KatiSuffix()+katiPackageSuffix+".ninja")
+}
+
func (c *configImpl) SoongNinjaFile() string {
return filepath.Join(c.SoongOutDir(), "build.ninja")
}
@@ -535,6 +543,10 @@
return filepath.Join(c.ProductOut(), "previous_build_config.mk")
}
+func (c *configImpl) KatiPackageMkDir() string {
+ return filepath.Join(c.ProductOut(), "obj", "CONFIG", "kati_packaging")
+}
+
func (c *configImpl) hostOutRoot() string {
return filepath.Join(c.OutDir(), "host")
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index ffea841..ad57d02 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -32,8 +32,40 @@
//
// vars is the list of variables to read. The values will be put in the
// returned map.
+//
+// variables controlled by soong_ui directly are now returned without needing
+// to call into make, to retain compatibility.
func DumpMakeVars(ctx Context, config Config, goals, vars []string) (map[string]string, error) {
- return dumpMakeVars(ctx, config, goals, vars, false)
+ soongUiVars := map[string]func() string{
+ "OUT_DIR": func() string { return config.OutDir() },
+ "DIST_DIR": func() string { return config.DistDir() },
+ }
+
+ makeVars := make([]string, 0, len(vars))
+ for _, v := range vars {
+ if _, ok := soongUiVars[v]; !ok {
+ makeVars = append(makeVars, v)
+ }
+ }
+
+ var ret map[string]string
+ if len(makeVars) > 0 {
+ var err error
+ ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
+ if err != nil {
+ return ret, err
+ }
+ } else {
+ ret = make(map[string]string)
+ }
+
+ for _, v := range vars {
+ if f, ok := soongUiVars[v]; ok {
+ ret[v] = f()
+ }
+ }
+
+ return ret, nil
}
func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
@@ -48,7 +80,6 @@
"dump-many-vars",
"MAKECMDGOALS="+strings.Join(goals, " "))
cmd.Environment.Set("CALLED_FROM_SETUP", "true")
- cmd.Environment.Set("BUILD_SYSTEM", "build/make/core")
if write_soong_vars {
cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
}
diff --git a/ui/build/environment.go b/ui/build/environment.go
index cbeeb4b..d8ff7f2 100644
--- a/ui/build/environment.go
+++ b/ui/build/environment.go
@@ -75,6 +75,17 @@
*e = out
}
+// Allow removes all keys that are not present in the input list
+func (e *Environment) Allow(keys ...string) {
+ out := (*e)[:0]
+ for _, env := range *e {
+ if key, _, ok := decodeKeyValue(env); ok && inList(key, keys) {
+ out = append(out, env)
+ }
+ }
+ *e = out
+}
+
// Environ returns the []string required for exec.Cmd.Env
func (e *Environment) Environ() []string {
return []string(*e)
diff --git a/ui/build/environment_test.go b/ui/build/environment_test.go
index 0294dac..37f500f 100644
--- a/ui/build/environment_test.go
+++ b/ui/build/environment_test.go
@@ -56,6 +56,15 @@
}
}
+func TestEnvAllow(t *testing.T) {
+ initial := &Environment{"TEST=1", "TEST2=0", "TEST3=2"}
+ initial.Allow("TEST3", "TEST")
+ got := initial.Environ()
+ if len(got) != 2 || got[0] != "TEST=1" || got[1] != "TEST3=2" {
+ t.Errorf("Expected [TEST=1 TEST3=2], got: %v", got)
+ }
+}
+
const testKatiEnvFileContents = `#!/bin/sh
# Generated by kati unknown
diff --git a/ui/build/kati.go b/ui/build/kati.go
index 546fd1a..56e9a88 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -28,6 +28,7 @@
const katiBuildSuffix = ""
const katiCleanspecSuffix = "-cleanspec"
+const katiPackageSuffix = "-package"
// genKatiSuffix creates a suffix for kati-generated files so that we can cache
// them based on their inputs. So this should encode all common changes to Kati
@@ -59,7 +60,7 @@
}
}
-func runKati(ctx Context, config Config, extraSuffix string, args []string) {
+func runKati(ctx Context, config Config, extraSuffix string, args []string, envFunc func(*Environment)) {
executable := config.PrebuiltBuildTool("ckati")
args = append([]string{
"--ninja",
@@ -80,10 +81,6 @@
"--kati_stats",
}, args...)
- args = append(args,
- "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
- "TARGET_DEVICE_DIR="+config.TargetDeviceDir())
-
cmd := Command(ctx, config, "ckati", executable, args...)
cmd.Sandbox = katiSandbox
pipe, err := cmd.StdoutPipe()
@@ -92,6 +89,8 @@
}
cmd.Stderr = cmd.Stdout
+ envFunc(cmd.Environment)
+
cmd.StartOrFatal()
status.KatiReader(ctx.Status.StartTool(), pipe)
cmd.WaitOrFatal()
@@ -103,7 +102,6 @@
args := []string{
"--writable", config.OutDir() + "/",
- "--writable", config.DistDir() + "/",
"-f", "build/make/core/main.mk",
}
@@ -125,9 +123,54 @@
args = append(args, config.KatiArgs()...)
- args = append(args, "SOONG_ANDROID_MK="+config.SoongAndroidMk())
+ args = append(args,
+ "SOONG_MAKEVARS_MK="+config.SoongMakeVarsMk(),
+ "SOONG_ANDROID_MK="+config.SoongAndroidMk(),
+ "TARGET_DEVICE_DIR="+config.TargetDeviceDir(),
+ "KATI_PACKAGE_MK_DIR="+config.KatiPackageMkDir())
- runKati(ctx, config, katiBuildSuffix, args)
+ runKati(ctx, config, katiBuildSuffix, args, func(env *Environment) {})
+}
+
+func runKatiPackage(ctx Context, config Config) {
+ ctx.BeginTrace("kati package")
+ defer ctx.EndTrace()
+
+ args := []string{
+ "--writable", config.DistDir() + "/",
+ "--werror_writable",
+ "--werror_implicit_rules",
+ "--werror_overriding_commands",
+ "--werror_real_to_phony",
+ "--werror_phony_looks_real",
+ "-f", "build/make/packaging/main.mk",
+ "KATI_PACKAGE_MK_DIR=" + config.KatiPackageMkDir(),
+ }
+
+ runKati(ctx, config, katiPackageSuffix, args, func(env *Environment) {
+ env.Allow([]string{
+ // Some generic basics
+ "LANG",
+ "LC_MESSAGES",
+ "PATH",
+ "PWD",
+ "TMPDIR",
+
+ // Tool configs
+ "JAVA_HOME",
+ "PYTHONDONTWRITEBYTECODE",
+
+ // Build configuration
+ "ANDROID_BUILD_SHELL",
+ "DIST_DIR",
+ "OUT_DIR",
+ }...)
+
+ if config.Dist() {
+ env.Set("DIST", "true")
+ env.Set("DIST_DIR", config.DistDir())
+ }
+ })
}
func runKatiCleanSpec(ctx Context, config Config) {
@@ -138,5 +181,7 @@
"--werror_implicit_rules",
"--werror_overriding_commands",
"-f", "build/make/core/cleanbuild.mk",
- })
+ "SOONG_MAKEVARS_MK=" + config.SoongMakeVarsMk(),
+ "TARGET_DEVICE_DIR=" + config.TargetDeviceDir(),
+ }, func(env *Environment) {})
}
diff --git a/ui/build/ninja.go b/ui/build/ninja.go
index 91cb475..c8f19d1 100644
--- a/ui/build/ninja.go
+++ b/ui/build/ninja.go
@@ -60,6 +60,8 @@
cmd.Environment.AppendFromKati(config.KatiEnvFile())
}
+ cmd.Environment.Set("DIST_DIR", config.DistDir())
+
// Allow both NINJA_ARGS and NINJA_EXTRA_ARGS, since both have been
// used in the past to specify extra ninja arguments.
if extra, ok := cmd.Environment.Get("NINJA_ARGS"); ok {
diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go
index 7e19da6..c4fcc20 100644
--- a/ui/build/paths/config.go
+++ b/ui/build/paths/config.go
@@ -101,7 +101,6 @@
"ls": Allowed,
"lsof": Allowed,
"m4": Allowed,
- "make": Log,
"md5sum": Allowed,
"mkdir": Allowed,
"mktemp": Allowed,
@@ -148,7 +147,6 @@
"which": Allowed,
"whoami": Allowed,
"xargs": Allowed,
- "xmllint": Log,
"xxd": Allowed,
"xz": Allowed,
"zip": Allowed,
diff --git a/ui/status/kati.go b/ui/status/kati.go
index 552a9e9..7c26d42 100644
--- a/ui/status/kati.go
+++ b/ui/status/kati.go
@@ -24,7 +24,7 @@
)
var katiError = regexp.MustCompile(`^(\033\[1m)?[^ ]+:[0-9]+: (\033\[31m)?error:`)
-var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including [^ ]+|initializing build system|finishing build rules|writing build rules) ...)$`)
+var katiIncludeRe = regexp.MustCompile(`^(\[(\d+)/(\d+)] )?((including [^ ]+|initializing (build|packaging) system|finishing (build|packaging) rules|writing (build|packaging) rules) ...)$`)
var katiLogRe = regexp.MustCompile(`^\*kati\*: `)
var katiNinjaMissing = regexp.MustCompile("^[^ ]+ is missing, regenerating...$")