Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang] Add support for -rpath on AIX #89279

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

madanial0
Copy link
Contributor

Add support for existing -rpath option to AIX. Prior to this PR, if -rpath is passed on AIX it gets passed to the linker and crashes as the linker on AIX cannot process it.

@madanial0 madanial0 requested a review from daltenty April 18, 2024 17:41
@madanial0 madanial0 self-assigned this Apr 18, 2024
@llvmbot llvmbot added clang Clang issues not falling into any other category backend:PowerPC clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' labels Apr 18, 2024
@llvmbot
Copy link
Member

llvmbot commented Apr 18, 2024

@llvm/pr-subscribers-clang-driver
@llvm/pr-subscribers-clang

@llvm/pr-subscribers-backend-powerpc

Author: None (madanial0)

Changes

Add support for existing -rpath option to AIX. Prior to this PR, if -rpath is passed on AIX it gets passed to the linker and crashes as the linker on AIX cannot process it.


Full diff: https://github.com/llvm/llvm-project/pull/89279.diff

4 Files Affected:

  • (modified) clang/lib/Driver/ToolChains/AIX.cpp (+28)
  • (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+4)
  • (added) clang/test/Driver/aix-rpath.c (+41)
  • (modified) clang/test/Driver/at_file_missing.c (+6-2)
diff --git a/clang/lib/Driver/ToolChains/AIX.cpp b/clang/lib/Driver/ToolChains/AIX.cpp
index c1b350893b3744..59427716a56fc6 100644
--- a/clang/lib/Driver/ToolChains/AIX.cpp
+++ b/clang/lib/Driver/ToolChains/AIX.cpp
@@ -230,6 +230,34 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
   // '-bnocdtors' that '-Wl' might forward.
   CmdArgs.push_back("-bcdtors:all:0:s");
 
+  if (Args.hasArg(options::OPT_rpath)) {
+    for (const auto &bopt : Args.getAllArgValues(options::OPT_b))
+      // Check -b opts prefix for "libpath:" or exact match for "nolibpath"
+      if (!bopt.rfind("libpath:", 0) || bopt == "nolibpath")
+        D.Diag(diag::err_drv_cannot_mix_options) << "-rpath"
+                                                 << "-b" + bopt;
+
+    for (const auto &wlopt : Args.getAllArgValues(options::OPT_Wl_COMMA))
+      // Check -Wl, opts prefix for "-blibpath:" or exact match for
+      // "-bnolibpath"
+      if (!wlopt.rfind("-blibpath:", 0) || wlopt == "-bnolibpath")
+        D.Diag(diag::err_drv_cannot_mix_options) << "-rpath"
+                                                 << "-Wl," + wlopt;
+
+    for (const auto &xopt : Args.getAllArgValues(options::OPT_Xlinker))
+      // Check -Xlinker opts prefix for "-blibpath:" or exact match for
+      // "-bnolibpath"
+      if (!xopt.rfind("-blibpath:", 0) || xopt == "-bnolibpath")
+        D.Diag(diag::err_drv_cannot_mix_options) << "-rpath"
+                                                 << "-Xlinker " + xopt;
+
+    std::string BlibPathStr = "";
+    for (const auto &dir : Args.getAllArgValues(options::OPT_rpath))
+      BlibPathStr += dir + ":";
+    BlibPathStr += "/usr/lib:/lib";
+    CmdArgs.push_back(Args.MakeArgString(Twine("-blibpath:") + BlibPathStr));
+  }
+
   // Specify linker input file(s).
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index f10aa4dfaa9ddd..d38e9fe09f7d18 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -436,6 +436,10 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs,
       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
     else if (A.getOption().matches(options::OPT_Z_reserved_lib_cckext))
       TC.AddCCKextLibArgs(Args, CmdArgs);
+    // Do not pass OPT_rpath to linker in AIX
+    else if (A.getOption().matches(options::OPT_rpath) &&
+             TC.getTriple().isOSAIX())
+      continue;
     else
       A.renderAsInput(Args, CmdArgs);
   }
diff --git a/clang/test/Driver/aix-rpath.c b/clang/test/Driver/aix-rpath.c
new file mode 100644
index 00000000000000..c717307282ff43
--- /dev/null
+++ b/clang/test/Driver/aix-rpath.c
@@ -0,0 +1,41 @@
+// Test -R passing search directories to the linker
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -bfakelibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -bfakelibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bloadmap:-blibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bloadmap:-blibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-fakeblibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck %s
+// RUN: %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-fakeblibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck %s
+
+// RUN: %clang %s -bsvr4 -Wl,-R/dir1/ -Wl,-blibpath:/dir2/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-LAST %s
+// RUN: %clang %s -bsvr4 -Wl,-R/dir1/ -Wl,-blibpath:/dir2/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-LAST %s
+// RUN: %clang %s -bsvr4 -Xlinker -R/dir1/ -Xlinker -blibpath:/dir2/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-LAST %s
+// RUN: %clang %s -bsvr4 -Xlinker -R/dir1/ -Xlinker -blibpath:/dir2/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-LAST %s
+//
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -bnolibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -bnolibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnolibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERWLBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnolibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERWLBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnoentry,-bnolibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERWLBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnoentry,-bnolibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERWLBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Xlinker -bnolibpath -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERXBN %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Xlinker -bnolibpath -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERXBN %s
+//
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -blibpath:/dir3/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERB %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -blibpath:/dir3/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERB %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-blibpath:/dir3/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERWL %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-blibpath:/dir3/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERWL %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnoentr,-blibpath:/dir3/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERWL %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Wl,-bnoentr,-blibpath:/dir3/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERWL %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Xlinker -blibpath:/dir3/ -### 2>&1  --target=powerpc-ibm-aix | FileCheck --check-prefix=CHECK-ERX %s
+// RUN: not %clang %s -rpath /dir1/ -rpath /dir2/ -Xlinker -blibpath:/dir3/ -### 2>&1  --target=powerpc64-ibm-aix | FileCheck --check-prefix=CHECK-ERX %s
+
+//CHECK: -blibpath:/dir1/:/dir2/:/usr/lib:/lib
+//CHECK-LAST: -blibpath:/dir2/
+//CHECK-ERBN: error: cannot specify '-bnolibpath' along with '-rpath'
+//CHECK-ERWLBN: error: cannot specify '-Wl,-bnolibpath' along with '-rpath'
+//CHECK-ERXBN: error: cannot specify '-Xlinker -bnolibpath' along with '-rpath'
+//CHECK-ERB: error: cannot specify '-blibpath:/dir3/' along with '-rpath'
+//CHECK-ERWL: error: cannot specify '-Wl,-blibpath:/dir3/' along with '-rpath'
+//CHECK-ERX: error: cannot specify '-Xlinker -blibpath:/dir3/' along with '-rpath'
diff --git a/clang/test/Driver/at_file_missing.c b/clang/test/Driver/at_file_missing.c
index 23645a5d3f93a2..306c53bf8c757c 100644
--- a/clang/test/Driver/at_file_missing.c
+++ b/clang/test/Driver/at_file_missing.c
@@ -2,6 +2,10 @@
 // stream, and also that @file arguments continue to be processed.
 
 // RUN: echo "-D FOO" > %t.args
-// RUN: %clang -rpath @executable_path/../lib @%t.args %s -### 2>&1 | FileCheck %s
-// CHECK: "-D" "FOO"
+// RUN: %clang -rpath @executable_path/../lib @%t.args %s -### 2>&1 | FileCheck %s \
+// RUN:        --check-prefixes=%if system-aix %{CHECK-AIX,CHECK-ALL%} \
+// RUN:        %else %{CHECK-ALL,CHECK%}
+
+// CHECK-ALL: "-D" "FOO"
 // CHECK: "-rpath" "@executable_path/../lib"
+// CHECK-AIX: "-blibpath:@executable_path/../lib:/usr/lib:/lib"

Copy link

github-actions bot commented Apr 18, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:PowerPC clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang Clang issues not falling into any other category platform:aix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants