[clang] Use platform specific calls to get the executable absolute path (PR #68091)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 3 04:23:14 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

<details>
<summary>Changes</summary>

This patch fixes #<!-- -->66704.

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


1 Files Affected:

- (modified) clang/tools/driver/driver.cpp (+61) 


``````````diff
diff --git a/clang/tools/driver/driver.cpp b/clang/tools/driver/driver.cpp
index 531b5b4a61c1804..45e1469aafca95e 100644
--- a/clang/tools/driver/driver.cpp
+++ b/clang/tools/driver/driver.cpp
@@ -57,6 +57,15 @@ using namespace clang;
 using namespace clang::driver;
 using namespace llvm::opt;
 
+#if defined(__linux__)
+#include <unistd.h>
+#elif defined(__APPLE__)
+#include <libproc.h>
+#include <unistd.h>
+#elif defined(__MINGW32__)
+#include <windows.h>
+#endif
+
 std::string GetExecutablePath(const char *Argv0, bool CanonicalPrefixes) {
   if (!CanonicalPrefixes) {
     SmallString<128> ExecutablePath(Argv0);
@@ -331,6 +340,56 @@ static void SetInstallDir(SmallVectorImpl<const char *> &argv,
   // path being a symlink.
   SmallString<128> InstalledPath(argv[0]);
 
+#if defined(__linux__)
+
+  char ProcessAbsolutePath[PATH_MAX];
+
+  int len = readlink("/proc/self/exe", ProcessAbsolutePath,
+                     sizeof(ProcessAbsolutePath) - 1);
+  if (len <= 0) {
+    llvm::errs() << "Internal error: readlink(\"/proc/self/exe\") failed with "
+                 << strerror(errno) << "\n";
+    exit(1);
+  }
+
+  ProcessAbsolutePath[len] = 0;
+  InstalledPath = ProcessAbsolutePath;
+
+#elif defined(__APPLE__)
+
+  // The size must be higher than PROC_PIDPATHINFO_SIZE, otherwise the call
+  // fails with ENOMEM (12) - Cannot allocate memory.
+  // https://opensource.apple.com/source/Libc/Libc-498/darwin/libproc.c
+  char ProcessAbsolutePath[PROC_PIDPATHINFO_SIZE + 1];
+
+  int len = proc_pidpath(getpid(), ProcessAbsolutePath,
+                         sizeof(ProcessAbsolutePath) - 1);
+  if (len <= 0) {
+    llvm::errs() << "Internal error: proc_pidpath() failed with "
+                 << strerror(errno) << "\n";
+    exit(1);
+  }
+
+  ProcessAbsolutePath[len] = 0;
+  InstalledPath = ProcessAbsolutePath;
+
+#elif defined(__MINGW32__)
+
+  char ProcessAbsolutePath[PATH_MAX];
+
+  len = GetModuleFileName(NULL, ProcessAbsolutePath,
+                          sizeof(ProcessAbsolutePath) - 1);
+  if (len <= 0) {
+    llvm::errs() << "Internal error: GetModuleFileName() failed with "
+                 << strerror(errno) << "\n";
+    exit(1);
+  }
+
+  ProcessAbsolutePath[len] = 0;
+  InstalledPath = ProcessAbsolutePath;
+
+#else
+
   // Do a PATH lookup, if there are no directory components.
   if (llvm::sys::path::filename(InstalledPath) == InstalledPath)
     if (llvm::ErrorOr<std::string> Tmp = llvm::sys::findProgramByName(
@@ -341,6 +400,8 @@ static void SetInstallDir(SmallVectorImpl<const char *> &argv,
   if (CanonicalPrefixes)
     llvm::sys::fs::make_absolute(InstalledPath);
 
+#endif
+
   StringRef InstalledPathParent(llvm::sys::path::parent_path(InstalledPath));
   if (llvm::sys::fs::exists(InstalledPathParent))
     TheDriver.setInstalledDir(InstalledPathParent);

``````````

</details>


https://github.com/llvm/llvm-project/pull/68091


More information about the cfe-commits mailing list