[PATCH] D47578: Do not enforce absolute path argv0 in windows

Takuto Ikuta via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 31 09:06:42 PDT 2018


takuto.ikuta updated this revision to Diff 149304.
takuto.ikuta edited the summary of this revision.

https://reviews.llvm.org/D47578

Files:
  llvm/lib/Support/Windows/Process.inc


Index: llvm/lib/Support/Windows/Process.inc
===================================================================
--- llvm/lib/Support/Windows/Process.inc
+++ llvm/lib/Support/Windows/Process.inc
@@ -209,9 +209,7 @@
 }
 
 static std::error_code ExpandShortFileName(const wchar_t *Arg,
-                                           SmallVectorImpl<const char *> &Args,
-                                           BumpPtrAllocator &Alloc) {
-  SmallVector<wchar_t, MAX_PATH> LongPath;
+                                           SmallVectorImpl<wchar_t> &LongPath) {
   DWORD Length = GetLongPathNameW(Arg, LongPath.data(), LongPath.capacity());
   if (Length == 0)
     return mapWindowsError(GetLastError());
@@ -222,7 +220,51 @@
     return mapWindowsError(ERROR_INSUFFICIENT_BUFFER);
   }
   LongPath.set_size(Length);
-  return ConvertAndPushArg(LongPath.data(), Args, Alloc);
+  return std::error_code();
+}
+
+static std::error_code GetLongArgv0Path(const wchar_t *Argv0,
+                                        SmallVectorImpl<const char *> &Args,
+                                        BumpPtrAllocator &Alloc) {
+  // The first argument may contain just the name of the executable (e.g.,
+  // "clang") rather than the full path, so swap it with the full path.
+  wchar_t ModuleName[MAX_PATH];
+  int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
+  SmallVector<wchar_t, 128> UTF16LongpathArgv0, UTF16Argv0;
+
+  if (0 < Length && Length < MAX_PATH)
+    Argv0 = ModuleName;
+
+  // If the first argument is a shortened (8.3) name (which is possible even
+  // if we got the module name), the driver will have trouble distinguishing it
+  // (e.g., clang.exe v. clang++.exe), so expand it now.
+  std::error_code ec = ExpandShortFileName(Argv0, UTF16LongpathArgv0);
+  if (ec)
+    return ec;
+
+  // Replace filename in original argv0 with expanded filename.
+  // This may change argv0 like below,
+  // * clang -> clang.exe (just add extension)
+  // * CLANG_~1.EXE -> clang++.exe (extend shorname)
+  // This is for keeping relativeness of original argv0 path.
+  SmallVector<char, MAX_PATH> UTF8LongPathArgv0;
+  ec = windows::UTF16ToUTF8(UTF16LongpathArgv0.data(), UTF16LongpathArgv0.size(),
+                            UTF8LongPathArgv0);
+  if (ec)
+    return ec;
+
+  SmallVector<char, MAX_PATH> UTF8Argv0;
+  ec = windows::UTF16ToUTF8(Argv0, wcslen(Argv0), UTF8Argv0);
+  if (ec)
+    return ec;
+
+  sys::path::remove_filename(UTF8Argv0);
+  sys::path::append(UTF8Argv0, sys::path::filename(UTF8LongPathArgv0.data()));
+  ec = windows::UTF8ToUTF16(UTF8Argv0.data(), UTF16Argv0);
+  if (ec)
+    return ec;
+
+  return ConvertAndPushArg(UTF16Argv0.data(), Args, Alloc);
 }
 
 std::error_code
@@ -235,19 +277,7 @@
     return mapWindowsError(::GetLastError());
 
   Args.reserve(ArgCount);
-  std::error_code ec;
-
-  // The first argument may contain just the name of the executable (e.g.,
-  // "clang") rather than the full path, so swap it with the full path.
-  wchar_t ModuleName[MAX_PATH];
-  int Length = ::GetModuleFileNameW(NULL, ModuleName, MAX_PATH);
-  if (0 < Length && Length < MAX_PATH)
-    UnicodeCommandLine[0] = ModuleName;
-
-  // If the first argument is a shortened (8.3) name (which is possible even
-  // if we got the module name), the driver will have trouble distinguishing it
-  // (e.g., clang.exe v. clang++.exe), so expand it now.
-  ec = ExpandShortFileName(UnicodeCommandLine[0], Args, Alloc);
+  std::error_code ec = GetLongArgv0Path(UnicodeCommandLine[0], Args, Alloc);
 
   for (int i = 1; i < ArgCount && !ec; ++i) {
     ec = WildcardExpand(UnicodeCommandLine[i], Args, Alloc);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47578.149304.patch
Type: text/x-patch
Size: 3648 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180531/b97d9371/attachment.bin>


More information about the llvm-commits mailing list