1// Copyright 2020 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package config 16 17import ( 18 "strings" 19 20 "android/soong/android" 21) 22 23var ( 24 // This is a host toolchain but flags for device toolchain are required 25 // as the flags are actually for Bionic-based builds. 26 linuxCrossCflags = append(deviceGlobalCflags, 27 // clang by default enables PIC when the clang triple is set to *-android. 28 // See toolchain/llvm-project/clang/lib/Driver/ToolChains/CommonArgs.cpp#920. 29 // However, for this host target, we don't set "-android" to avoid __ANDROID__ macro 30 // which stands for "Android device target". Keeping PIC on is required because 31 // many modules we have (e.g. Bionic) assume PIC. 32 "-fpic", 33 34 // This is normally in ClangExtraTargetCflags, but that's for device and we need 35 // the same for host 36 "-nostdlibinc", 37 ) 38 39 linuxCrossLdflags = []string{ 40 "-Wl,-z,noexecstack", 41 "-Wl,-z,relro", 42 "-Wl,-z,now", 43 "-Wl,--build-id=md5", 44 "-Wl,--fatal-warnings", 45 "-Wl,--no-undefined-version", 46 } 47 48 linuxCrossLldflags = append(linuxCrossLdflags, 49 "-Wl,--compress-debug-sections=zstd", 50 ) 51 52 // Embed the linker into host bionic binaries. This is needed to support host bionic, 53 // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be 54 // either an absolute path, or relative from CWD. To work around this, we extract 55 // the load sections from the runtime linker ELF binary and embed them into each host 56 // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static 57 // binary, and then we use a special entry point to fix up the arguments passed by 58 // the kernel before jumping to the embedded linker. 59 linuxArm64CrtBeginSharedBinary = append(android.CopyOf(bionicCrtBeginSharedBinary), 60 "host_bionic_linker_script") 61) 62 63func init() { 64 pctx.StaticVariable("LinuxBionicArm64Cflags", strings.Join(linuxCrossCflags, " ")) 65 pctx.StaticVariable("LinuxBionicArm64Ldflags", strings.Join(linuxCrossLdflags, " ")) 66 pctx.StaticVariable("LinuxBionicArm64Lldflags", strings.Join(linuxCrossLldflags, " ")) 67} 68 69// toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android 70// target. The overridden methods below show the differences. 71type toolchainLinuxBionicArm64 struct { 72 toolchainArm64 73} 74 75func (toolchainLinuxBionicArm64) ClangTriple() string { 76 // Note the absence of "-android" suffix. The compiler won't define __ANDROID__ 77 return "aarch64-linux" 78} 79 80func (toolchainLinuxBionicArm64) Cflags() string { 81 // The inherited flags + extra flags 82 return "${config.Arm64Cflags} ${config.LinuxBionicArm64Cflags}" 83} 84 85func (toolchainLinuxBionicArm64) CrtBeginSharedBinary() []string { 86 return linuxArm64CrtBeginSharedBinary 87} 88 89func linuxBionicArm64ToolchainFactory(arch android.Arch) Toolchain { 90 // for host, default to armv8-a 91 toolchainCflags := []string{"-march=armv8-a"} 92 93 // We don't specify CPU architecture for host. Conservatively assume 94 // the host CPU needs the fix 95 extraLdflags := "-Wl,--fix-cortex-a53-843419" 96 97 ret := toolchainLinuxBionicArm64{} 98 99 // add the extra ld and lld flags 100 ret.toolchainArm64.ldflags = strings.Join([]string{ 101 "${config.Arm64Ldflags}", 102 "${config.LinuxBionicArm64Ldflags}", 103 extraLdflags, 104 }, " ") 105 ret.toolchainArm64.lldflags = strings.Join([]string{ 106 "${config.Arm64Lldflags}", 107 "${config.LinuxBionicArm64Ldflags}", 108 extraLdflags, 109 }, " ") 110 ret.toolchainArm64.toolchainCflags = strings.Join(toolchainCflags, " ") 111 return &ret 112} 113 114func init() { 115 registerToolchainFactory(android.LinuxBionic, android.Arm64, linuxBionicArm64ToolchainFactory) 116} 117