Add linux_musl arm+arm64

Add toolchains to support cross compiling to aarch64-linux-musl and
arm-linux-musleabihf.

Bug: 236052820
Test: build arm and arm64 musl sysroots
Change-Id: I47a9322929baff2492c6e8db989ece01fcbeb133
diff --git a/android/arch.go b/android/arch.go
index cbf77c7..382a7df 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -307,7 +307,7 @@
 	// Linux is the OS for the Linux kernel plus the glibc runtime.
 	Linux = newOsType("linux_glibc", Host, false, X86, X86_64)
 	// LinuxMusl is the OS for the Linux kernel plus the musl runtime.
-	LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64)
+	LinuxMusl = newOsType("linux_musl", Host, false, X86, X86_64, Arm64, Arm)
 	// Darwin is the OS for MacOS/Darwin host machines.
 	Darwin = newOsType("darwin", Host, false, Arm64, X86_64)
 	// LinuxBionic is the OS for the Linux kernel plus the Bionic libc runtime, but without the
diff --git a/android/paths.go b/android/paths.go
index e0e5ae5..d5cec9a 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1739,10 +1739,16 @@
 		partionPaths = []string{"target", "product", ctx.Config().DeviceName(), partition}
 	} else {
 		osName := os.String()
-		if os == Linux || os == LinuxMusl {
+		if os == Linux {
 			// instead of linux_glibc
 			osName = "linux"
 		}
+		if os == LinuxMusl && ctx.Config().UseHostMusl() {
+			// When using musl instead of glibc, use "linux" instead of "linux_musl".  When cross
+			// compiling we will still use "linux_musl".
+			osName = "linux"
+		}
+
 		// SOONG_HOST_OUT is set to out/host/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
 		// and HOST_PREBUILT_ARCH is forcibly set to x86 even on x86_64 hosts. We don't seem
 		// to have a plan to fix it (see the comment in build/make/core/envsetup.mk).
diff --git a/bazel/configurability.go b/bazel/configurability.go
index 7355ac7..0ab49eb 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -43,6 +43,8 @@
 	osArchDarwinX86_64      = "darwin_x86_64"
 	osArchLinuxX86          = "linux_glibc_x86"
 	osArchLinuxX86_64       = "linux_glibc_x86_64"
+	osArchLinuxMuslArm      = "linux_musl_arm"
+	osArchLinuxMuslArm64    = "linux_musl_arm64"
 	osArchLinuxMuslX86      = "linux_musl_x86"
 	osArchLinuxMuslX86_64   = "linux_musl_x86_64"
 	osArchLinuxBionicArm64  = "linux_bionic_arm64"
@@ -101,6 +103,8 @@
 		osArchDarwinX86_64:         "//build/bazel/platforms/os_arch:darwin_x86_64",
 		osArchLinuxX86:             "//build/bazel/platforms/os_arch:linux_glibc_x86",
 		osArchLinuxX86_64:          "//build/bazel/platforms/os_arch:linux_glibc_x86_64",
+		osArchLinuxMuslArm:         "//build/bazel/platforms/os_arch:linux_musl_arm",
+		osArchLinuxMuslArm64:       "//build/bazel/platforms/os_arch:linux_musl_arm64",
 		osArchLinuxMuslX86:         "//build/bazel/platforms/os_arch:linux_musl_x86",
 		osArchLinuxMuslX86_64:      "//build/bazel/platforms/os_arch:linux_musl_x86_64",
 		osArchLinuxBionicArm64:     "//build/bazel/platforms/os_arch:linux_bionic_arm64",
diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go
index ea58086..52688d9 100644
--- a/bp2build/cc_object_conversion_test.go
+++ b/bp2build/cc_object_conversion_test.go
@@ -414,6 +414,7 @@
             "bionic_arm64.cpp",
         ],
         "//build/bazel/platforms/os_arch:linux_glibc_x86": ["linux_x86.cpp"],
+        "//build/bazel/platforms/os_arch:linux_musl_arm64": ["linux_arm64.cpp"],
         "//build/bazel/platforms/os_arch:linux_musl_x86": ["linux_x86.cpp"],
         "//conditions:default": [],
     })`,
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index 1a21c13..64a121e 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -24,6 +24,7 @@
         "x86_device.go",
         "x86_64_device.go",
 
+        "arm_linux_host.go",
         "darwin_host.go",
         "x86_linux_host.go",
         "x86_linux_bionic_host.go",
diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go
index 5c7f926..2d316e6 100644
--- a/cc/config/arm64_linux_host.go
+++ b/cc/config/arm64_linux_host.go
@@ -64,25 +64,25 @@
 
 // toolchain config for ARM64 Linux CrossHost. Almost everything is the same as the ARM64 Android
 // target. The overridden methods below show the differences.
-type toolchainLinuxArm64 struct {
+type toolchainLinuxBionicArm64 struct {
 	toolchainArm64
 }
 
-func (toolchainLinuxArm64) ClangTriple() string {
+func (toolchainLinuxBionicArm64) ClangTriple() string {
 	// Note the absence of "-android" suffix. The compiler won't define __ANDROID__
 	return "aarch64-linux"
 }
 
-func (toolchainLinuxArm64) Cflags() string {
+func (toolchainLinuxBionicArm64) Cflags() string {
 	// The inherited flags + extra flags
 	return "${config.Arm64Cflags} ${config.LinuxBionicArm64Cflags}"
 }
 
-func (toolchainLinuxArm64) CrtBeginSharedBinary() []string {
+func (toolchainLinuxBionicArm64) CrtBeginSharedBinary() []string {
 	return linuxArm64CrtBeginSharedBinary
 }
 
-func linuxArm64ToolchainFactory(arch android.Arch) Toolchain {
+func linuxBionicArm64ToolchainFactory(arch android.Arch) Toolchain {
 	archVariant := "armv8-a" // for host, default to armv8-a
 	toolchainCflags := []string{arm64ArchVariantCflagsVar[archVariant]}
 
@@ -90,7 +90,7 @@
 	// the host CPU needs the fix
 	extraLdflags := "-Wl,--fix-cortex-a53-843419"
 
-	ret := toolchainLinuxArm64{}
+	ret := toolchainLinuxBionicArm64{}
 
 	// add the extra ld and lld flags
 	ret.toolchainArm64.ldflags = strings.Join([]string{
@@ -108,5 +108,5 @@
 }
 
 func init() {
-	registerToolchainFactory(android.LinuxBionic, android.Arm64, linuxArm64ToolchainFactory)
+	registerToolchainFactory(android.LinuxBionic, android.Arm64, linuxBionicArm64ToolchainFactory)
 }
diff --git a/cc/config/arm_linux_host.go b/cc/config/arm_linux_host.go
new file mode 100644
index 0000000..525fb5d
--- /dev/null
+++ b/cc/config/arm_linux_host.go
@@ -0,0 +1,174 @@
+// Copyright 2022 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 config
+
+import "android/soong/android"
+
+var (
+	linuxArmCflags = []string{
+		"-march=armv7a",
+	}
+
+	linuxArm64Cflags = []string{}
+
+	linuxArmLdflags = []string{
+		"-march=armv7a",
+	}
+
+	linuxArm64Ldflags = []string{}
+)
+
+func init() {
+	exportedVars.ExportStringListStaticVariable("LinuxArmCflags", linuxArmCflags)
+	exportedVars.ExportStringListStaticVariable("LinuxArm64Cflags", linuxArm64Cflags)
+	exportedVars.ExportStringListStaticVariable("LinuxArmLdflags", linuxArmLdflags)
+	exportedVars.ExportStringListStaticVariable("LinuxArmLldflags", linuxArmLdflags)
+	exportedVars.ExportStringListStaticVariable("LinuxArm64Ldflags", linuxArm64Ldflags)
+	exportedVars.ExportStringListStaticVariable("LinuxArm64Lldflags", linuxArm64Ldflags)
+
+	exportedVars.ExportStringListStaticVariable("LinuxArmYasmFlags", []string{"-f elf32 -m arm"})
+	exportedVars.ExportStringListStaticVariable("LinuxArm64YasmFlags", []string{"-f elf64 -m aarch64"})
+
+}
+
+// Musl arm+arm64
+type toolchainLinuxArm struct {
+	toolchain32Bit
+	toolchainLinux
+}
+
+type toolchainLinuxArm64 struct {
+	toolchain64Bit
+	toolchainLinux
+}
+
+func (t *toolchainLinuxArm) Name() string {
+	return "arm"
+}
+
+func (t *toolchainLinuxArm64) Name() string {
+	return "arm64"
+}
+
+func (t *toolchainLinuxArm) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxArmCflags}"
+}
+
+func (t *toolchainLinuxArm) Cppflags() string {
+	return ""
+}
+
+func (t *toolchainLinuxArm64) Cflags() string {
+	return "${config.LinuxCflags} ${config.LinuxArm64Cflags}"
+}
+
+func (t *toolchainLinuxArm64) Cppflags() string {
+	return ""
+}
+
+func (t *toolchainLinuxArm) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxArmLdflags}"
+}
+
+func (t *toolchainLinuxArm) Lldflags() string {
+	return "${config.LinuxLldflags} ${config.LinuxArmLldflags}"
+}
+
+func (t *toolchainLinuxArm64) Ldflags() string {
+	return "${config.LinuxLdflags} ${config.LinuxArm64Ldflags}"
+}
+
+func (t *toolchainLinuxArm64) Lldflags() string {
+	return "${config.LinuxLldflags} ${config.LinuxArm64Lldflags}"
+}
+
+func (t *toolchainLinuxArm) YasmFlags() string {
+	return "${config.LinuxArmYasmFlags}"
+}
+
+func (t *toolchainLinuxArm64) YasmFlags() string {
+	return "${config.LinuxArm64YasmFlags}"
+}
+
+func (toolchainLinuxArm) LibclangRuntimeLibraryArch() string {
+	return "arm"
+}
+
+func (toolchainLinuxArm64) LibclangRuntimeLibraryArch() string {
+	return "arm64"
+}
+
+func (t *toolchainLinuxArm) InstructionSetFlags(isa string) (string, error) {
+	// TODO: Is no thumb OK?
+	return t.toolchainBase.InstructionSetFlags("")
+}
+
+type toolchainLinuxMuslArm struct {
+	toolchainLinuxArm
+	toolchainMusl
+}
+
+type toolchainLinuxMuslArm64 struct {
+	toolchainLinuxArm64
+	toolchainMusl
+}
+
+func (t *toolchainLinuxMuslArm) ClangTriple() string {
+	return "arm-linux-musleabihf"
+}
+
+func (t *toolchainLinuxMuslArm) Cflags() string {
+	return t.toolchainLinuxArm.Cflags() + " " + t.toolchainMusl.Cflags()
+}
+
+func (t *toolchainLinuxMuslArm) Ldflags() string {
+	return t.toolchainLinuxArm.Ldflags() + " " + t.toolchainMusl.Ldflags()
+}
+
+func (t *toolchainLinuxMuslArm) Lldflags() string {
+	return t.toolchainLinuxArm.Lldflags() + " " + t.toolchainMusl.Lldflags()
+}
+
+func (t *toolchainLinuxMuslArm64) ClangTriple() string {
+	return "aarch64-linux-musl"
+}
+
+func (t *toolchainLinuxMuslArm64) Cflags() string {
+	return t.toolchainLinuxArm64.Cflags() + " " + t.toolchainMusl.Cflags()
+}
+
+func (t *toolchainLinuxMuslArm64) Ldflags() string {
+	return t.toolchainLinuxArm64.Ldflags() + " " + t.toolchainMusl.Ldflags()
+}
+
+func (t *toolchainLinuxMuslArm64) Lldflags() string {
+	return t.toolchainLinuxArm64.Lldflags() + " " + t.toolchainMusl.Lldflags()
+}
+
+var toolchainLinuxMuslArmSingleton Toolchain = &toolchainLinuxMuslArm{}
+var toolchainLinuxMuslArm64Singleton Toolchain = &toolchainLinuxMuslArm64{}
+
+func linuxMuslArmToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxMuslArmSingleton
+}
+
+func linuxMuslArm64ToolchainFactory(arch android.Arch) Toolchain {
+	return toolchainLinuxMuslArm64Singleton
+}
+
+func init() {
+	registerToolchainFactory(android.LinuxMusl, android.Arm, linuxMuslArmToolchainFactory)
+	registerToolchainFactory(android.LinuxMusl, android.Arm64, linuxMuslArm64ToolchainFactory)
+}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 3e9328b..42a112e 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -430,7 +430,7 @@
 	}
 
 	// Enable Memtag for all components in the include paths (for Aarch64 only)
-	if ctx.Arch().ArchType == android.Arm64 && ctx.toolchain().Bionic() {
+	if ctx.Arch().ArchType == android.Arm64 {
 		if ctx.Config().MemtagHeapSyncEnabledForPath(ctx.ModuleDir()) {
 			if s.Memtag_heap == nil {
 				s.Memtag_heap = proptools.BoolPtr(true)
@@ -460,17 +460,17 @@
 	}
 
 	// HWASan requires AArch64 hardware feature (top-byte-ignore).
-	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
+	if ctx.Arch().ArchType != android.Arm64 {
 		s.Hwaddress = nil
 	}
 
 	// SCS is only implemented on AArch64.
-	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
+	if ctx.Arch().ArchType != android.Arm64 {
 		s.Scs = nil
 	}
 
 	// Memtag_heap is only implemented on AArch64.
-	if ctx.Arch().ArchType != android.Arm64 || !ctx.toolchain().Bionic() {
+	if ctx.Arch().ArchType != android.Arm64 {
 		s.Memtag_heap = nil
 	}