[llvm-branch-commits] [clang] release/23.x: [Driver][OpenBSD] Use -no-pie instead of -nopie (#220464) (PR #220491)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Sep 1 22:57:21 PDT 2026


https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/220491

Backport 118efe7680bdc010ab984f8ae4505699f53bbca6 a2171756dd5d690faf30bafe63810d1dc6cdb342

Requested by: @brad0

>From 790fc0c2a1b61a8d1dd7fae5f160bd1070594679 Mon Sep 17 00:00:00 2001
From: Angel J <github at sl.jrz.me>
Date: Fri, 28 Aug 2026 22:48:00 -0700
Subject: [PATCH 1/2] [Driver][OpenBSD] Pass -pie for static PIE links
 (#216907)

OpenBSD uses `rcrt0.o` for static PIE executables. This startup object
references the linker-defined `_DYNAMIC` symbol.

OpenBSD's system linker defaults to PIE, which previously masked the
missing driver flag. An LLD cross-linker built on a non-OpenBSD host
does not share that default. Consequently,
`clang --target=...-openbsd -static` selects `rcrt0.o`, but LLD does not
create `_DYNAMIC`, causing the link to fail.

(cherry picked from commit 118efe7680bdc010ab984f8ae4505699f53bbca6)
---
 clang/lib/Driver/ToolChains/OpenBSD.cpp | 8 ++++++--
 clang/test/Driver/openbsd.c             | 1 +
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index 14680dc4b0e5b..fa36726534bed 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -119,6 +119,8 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   const bool Pie = Args.hasArg(options::OPT_pie);
   const bool Nopie = Args.hasArg(options::OPT_no_pie, options::OPT_nopie);
   const bool Relocatable = Args.hasArg(options::OPT_r);
+  const bool StaticPie =
+      Static && !Shared && !Profiling && !Nopie && !Relocatable;
   ArgStringList CmdArgs;
 
   // Silence warning for "clang -g foo.o -o foo"
@@ -156,7 +158,9 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     }
   }
 
-  if (Pie)
+  // OpenBSD's system linker defaults to PIE, but cross-linkers may not.
+  // Explicitly pass -pie so that rcrt0.o's reference to _DYNAMIC is resolved.
+  if (Pie || StaticPie)
     CmdArgs.push_back("-pie");
   if (Nopie || Profiling)
     CmdArgs.push_back("-nopie");
@@ -180,7 +184,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
     if (!Shared) {
       if (Profiling)
         crt0 = "gcrt0.o";
-      else if (Static && !Nopie)
+      else if (StaticPie)
         crt0 = "rcrt0.o";
       else
         crt0 = "crt0.o";
diff --git a/clang/test/Driver/openbsd.c b/clang/test/Driver/openbsd.c
index 1f12cfca9488b..e5e7f528e8fe7 100644
--- a/clang/test/Driver/openbsd.c
+++ b/clang/test/Driver/openbsd.c
@@ -104,6 +104,7 @@
 // CHECK-PIE: "{{.*}}crt0.o"
 // CHECK-PIE-NOT: "-nopie"
 // CHECK-PIE-FLAG: "-pie"
+// CHECK-STATIC-PIE: "-pie"
 // CHECK-STATIC-PIE: "{{.*}}rcrt0.o"
 // CHECK-STATIC-PIE-NOT: "-nopie"
 // CHECK-NOPIE: "-nopie" "{{.*}}crt0.o"

>From f54566aa3c49d203719b5e9b6316820907460f25 Mon Sep 17 00:00:00 2001
From: Keith Smiley <keithbsmiley at gmail.com>
Date: Tue, 1 Sep 2026 21:45:09 -0700
Subject: [PATCH 2/2] [Driver][OpenBSD] Use -no-pie instead of -nopie (#220464)

Downstream in OpenBSD there is a patch to add support for -nopie in lld
(which it has used by default since 2018). In this repo lld does not
support `-nopie`, so when building clang and lld, you cannot link an
executable with `clang -fno-pic`. Clang now uses the more widely used
spelling here so that toolchains built from this repo can cross compile
to OpenBSD successfully.

This change is an issue on OpenBSD if users passed a different linker
with `-fuse-ld` / `--ld-path` to `ld.bfd` which is still installed by
default but doesn't support the `-no-pie` spelling with their patches.

(cherry picked from commit a2171756dd5d690faf30bafe63810d1dc6cdb342)
---
 clang/lib/Driver/ToolChains/OpenBSD.cpp |  2 +-
 clang/test/Driver/openbsd.c             | 10 +++++-----
 clang/test/Driver/pic.c                 |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Driver/ToolChains/OpenBSD.cpp b/clang/lib/Driver/ToolChains/OpenBSD.cpp
index fa36726534bed..de5284ddf6e60 100644
--- a/clang/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/clang/lib/Driver/ToolChains/OpenBSD.cpp
@@ -163,7 +163,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   if (Pie || StaticPie)
     CmdArgs.push_back("-pie");
   if (Nopie || Profiling)
-    CmdArgs.push_back("-nopie");
+    CmdArgs.push_back("-no-pie");
 
   if (Triple.isLoongArch64() || Triple.isRISCV64()) {
     CmdArgs.push_back("-X");
diff --git a/clang/test/Driver/openbsd.c b/clang/test/Driver/openbsd.c
index e5e7f528e8fe7..7f18b9a16fb76 100644
--- a/clang/test/Driver/openbsd.c
+++ b/clang/test/Driver/openbsd.c
@@ -4,11 +4,11 @@
 // CHECK-LD-STATIC-EH: "-cc1" "-triple" "i686-pc-openbsd"
 // CHECK-LD-STATIC-EH: ld{{.*}}" "{{.*}}" "--eh-frame-hdr" "-Bstatic"
 
-// Check for profiling variants of libraries when linking and -nopie
+// Check for profiling variants of libraries when linking and -no-pie
 // RUN: %clang --target=i686-pc-openbsd -pg -pthread -### %s 2>&1 \
 // RUN:   | FileCheck --check-prefix=CHECK-PG %s
 // CHECK-PG: "-cc1" "-triple" "i686-pc-openbsd"
-// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld.so" "-nopie" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lcompiler_rt" "-lpthread_p" "-lc_p" "-lcompiler_rt" "{{.*}}crtend.o"
+// CHECK-PG: ld{{.*}}" "-e" "__start" "--eh-frame-hdr" "-dynamic-linker" "{{.*}}ld.so" "-no-pie" "-o" "a.out" "{{.*}}gcrt0.o" "{{.*}}crtbegin.o" "{{.*}}.o" "-lcompiler_rt" "-lpthread_p" "-lc_p" "-lcompiler_rt" "{{.*}}crtend.o"
 
 // Check for variants of crt* when creating shared libs
 // RUN: %clang --target=i686-pc-openbsd -pthread -shared -### %s 2>&1 \
@@ -102,12 +102,12 @@
 // RUN: %clang --target=i686-pc-openbsd -fno-pie -static -nopie -### %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-NOPIE %s
 // CHECK-PIE: "{{.*}}crt0.o"
-// CHECK-PIE-NOT: "-nopie"
+// CHECK-PIE-NOT: "-no-pie"
 // CHECK-PIE-FLAG: "-pie"
 // CHECK-STATIC-PIE: "-pie"
 // CHECK-STATIC-PIE: "{{.*}}rcrt0.o"
-// CHECK-STATIC-PIE-NOT: "-nopie"
-// CHECK-NOPIE: "-nopie" "{{.*}}crt0.o"
+// CHECK-STATIC-PIE-NOT: "-no-pie"
+// CHECK-NOPIE: "-no-pie" "{{.*}}crt0.o"
 
 // Check ARM float ABI
 // RUN: %clang --target=arm-unknown-openbsd -### -c %s 2>&1 \
diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c
index f5d0745422790..5d85c16607479 100644
--- a/clang/test/Driver/pic.c
+++ b/clang/test/Driver/pic.c
@@ -29,7 +29,7 @@
 // CHECK-PIE-LD: "Scrt1.o" "crti.o" "crtbeginS.o"
 // CHECK-PIE-LD: "crtendS.o" "crtn.o"
 //
-// CHECK-NOPIE-LD: "-nopie"
+// CHECK-NOPIE-LD: "-no-pie"
 //
 // CHECK-DYNAMIC-NO-PIC-32: "-mrelocation-model" "dynamic-no-pic"
 // CHECK-DYNAMIC-NO-PIC-32-NOT: "-pic-level"
@@ -264,7 +264,7 @@
 // RUN: %clang -c %s -target i386-pc-openbsd -fno-pie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NO-PIC
 //
-// On OpenBSD, -nopie needs to be passed through to the linker.
+// On OpenBSD, -no-pie needs to be passed through to the linker.
 // RUN: %clang %s -target i386-pc-openbsd -nopie -### 2>&1 \
 // RUN:   | FileCheck %s --check-prefix=CHECK-NOPIE-LD
 // Try with the alias



More information about the llvm-branch-commits mailing list