Prevent clang from using the x18 register on arm64.

This is achieved via the compiler flag -ffixed-x18 for non-LTO builds
and the linker flag -plugin-opt -mattr=+reserve-x18 for LTO builds.

This change should be reverted once we upgrade past LLVM r340889
which does this by default on Android.

Bug: 112907825
Bug: 111759196
Change-Id: I05473ddbb98319d87d442425b4d715647eae3a38
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/lto.go b/cc/lto.go
index 52b9a34..d9d2662 100644
--- a/cc/lto.go
+++ b/cc/lto.go
@@ -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/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)