Skip to content

[FR] disable rosegment in the driver once we no longer support bfd/gold #1294

@DanAlbert

Description

@DanAlbert

Once we no longer support gold and bfd we can hoist the rosegment disabling logic from the build systems into the driver so third-party build systems don't need to worry about this. Can't send this patch until then because gold and bfd don't understand the argument and there's no way for us to figure out which linker is used within the clang driver and LLD doesn't know it's targeting Android, let alone the Android version.

Don't know exactly when gold/bfd will be gone, but triaging to r23.

From debe246ff031a715732b4a1af270e6bc68c7a467 Mon Sep 17 00:00:00 2001
From: Dan Albert <danalbert@google.com>
Date: Thu, 25 Jun 2020 16:25:51 -0700
Subject: [PATCH] Disable rosegment for old Android versions.

The unwinder used by the crash handler on versions of Android prior to
API 29 did not correctly handle binaries built with rosegment, which is
enabled by default for LLD. Android only supports LLD, so it's not an
issue that this flag is not accepted by other linkers.
---
 clang/lib/Driver/ToolChains/Linux.cpp |  9 +++++++++
 clang/test/Driver/linux-ld.c          | 14 ++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 180350476c3..b0e62330ead 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -232,6 +232,15 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
     ExtraOpts.push_back("relro");
   }
 
+  if (Triple.isAndroid() && Triple.isAndroidVersionLT(29)) {
+    // https://github.com/android/ndk/issues/1196
+    // The unwinder used by the crash handler on versions of Android prior to
+    // API 29 did not correctly handle binaries built with rosegment, which is
+    // enabled by default for LLD. Android only supports LLD, so it's not an
+    // issue that this flag is not accepted by other linkers.
+    ExtraOpts.push_back("--no-rosegment");
+  }
+
   // Android ARM/AArch64 use max-page-size=4096 to reduce VMA usage. Note, lld
   // from 11 onwards default max-page-size to 65536 for both ARM and AArch64.
   if ((Triple.isARM() || Triple.isAArch64()) && Triple.isAndroid()) {
diff --git a/clang/test/Driver/linux-ld.c b/clang/test/Driver/linux-ld.c
index ec539522c25..afe7418cded 100644
--- a/clang/test/Driver/linux-ld.c
+++ b/clang/test/Driver/linux-ld.c
@@ -1092,6 +1092,20 @@
 // CHECK-ANDROID-HASH-STYLE-M: "{{.*}}ld{{(.exe)?}}"
 // CHECK-ANDROID-HASH-STYLE-M: "--hash-style=gnu"
 
+// Check that we pass --no-rosegment for pre-29 Android versions and do not for
+// 29+.
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=armv7-linux-android28 \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-ROSEGMENT-28 %s
+// CHECK-ANDROID-ROSEGMENT-28: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ANDROID-ROSEGMENT-28: "--no-rosegment"
+//
+// RUN: %clang %s -### -o %t.o 2>&1 \
+// RUN:     --target=armv7-linux-android29 \
+// RUN:   | FileCheck --check-prefix=CHECK-ANDROID-ROSEGMENT-29 %s
+// CHECK-ANDROID-ROSEGMENT-29: "{{.*}}ld{{(.exe)?}}"
+// CHECK-ANDROID-ROSEGMENT-29-NOT: "--no-rosegment"
+
 // RUN: %clang %s -### -o %t.o 2>&1 \
 // RUN:     --target=armv7-linux-android21 \
 // RUN:   | FileCheck --check-prefix=CHECK-ANDROID-NOEXECSTACK %s
-- 
2.27.0.111.gc72c7da667-goog

Metadata

Metadata

Assignees

Type

No type

Projects

Status

Unconfirmed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions