[Lldb-commits] [lldb] r264074 - Unicode support on Win32.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Tue Mar 22 10:58:10 PDT 2016


Author: zturner
Date: Tue Mar 22 12:58:09 2016
New Revision: 264074

URL: http://llvm.org/viewvc/llvm-project?rev=264074&view=rev
Log:
Unicode support on Win32.

Win32 API calls that are Unicode aware require wide character
strings, but LLDB uses UTF8 everywhere.  This patch does conversions
wherever necessary when passing strings into and out of Win32 API
calls.

Patch by Cameron
Differential Revision: http://reviews.llvm.org/D17107
Reviewed By: zturner, amccarth

Modified:
    lldb/trunk/cmake/modules/LLDBConfig.cmake
    lldb/trunk/include/lldb/Host/FileSystem.h
    lldb/trunk/include/lldb/Host/posix/HostInfoPosix.h
    lldb/trunk/include/lldb/Host/windows/HostInfoWindows.h
    lldb/trunk/packages/Python/lldbsuite/test/dotest.py
    lldb/trunk/source/Commands/CommandCompletions.cpp
    lldb/trunk/source/Core/ConnectionSharedMemory.cpp
    lldb/trunk/source/Core/Disassembler.cpp
    lldb/trunk/source/Host/common/File.cpp
    lldb/trunk/source/Host/common/FileSpec.cpp
    lldb/trunk/source/Host/posix/FileSystem.cpp
    lldb/trunk/source/Host/posix/HostInfoPosix.cpp
    lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp
    lldb/trunk/source/Host/windows/FileSystem.cpp
    lldb/trunk/source/Host/windows/Host.cpp
    lldb/trunk/source/Host/windows/HostInfoWindows.cpp
    lldb/trunk/source/Host/windows/HostProcessWindows.cpp
    lldb/trunk/source/Host/windows/PipeWindows.cpp
    lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp
    lldb/trunk/source/Host/windows/Windows.cpp
    lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
    lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
    lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
    lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
    lldb/trunk/source/Target/ProcessLaunchInfo.cpp
    lldb/trunk/tools/driver/Driver.cpp
    lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
    lldb/trunk/tools/lldb-mi/MIUtilFileStd.cpp
    lldb/trunk/tools/lldb-mi/Platform.h

Modified: lldb/trunk/cmake/modules/LLDBConfig.cmake
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/cmake/modules/LLDBConfig.cmake?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/cmake/modules/LLDBConfig.cmake (original)
+++ lldb/trunk/cmake/modules/LLDBConfig.cmake Tue Mar 22 12:58:09 2016
@@ -245,6 +245,11 @@ if( MSVC )
   )
 endif()
 
+# Use the Unicode (UTF-16) APIs by default on Win32
+if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+	add_definitions( /D _UNICODE /D UNICODE )
+endif()
+
 set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
 set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
 

Modified: lldb/trunk/include/lldb/Host/FileSystem.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/FileSystem.h?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/FileSystem.h (original)
+++ lldb/trunk/include/lldb/Host/FileSystem.h Tue Mar 22 12:58:09 2016
@@ -11,6 +11,8 @@
 #define liblldb_Host_FileSystem_h
 
 #include <stdint.h>
+#include <stdio.h>
+#include <sys/stat.h>
 
 #include "lldb/lldb-types.h"
 
@@ -23,6 +25,7 @@ class FileSystem
 {
   public:
     static const char *DEV_NULL;
+    static const char *PATH_CONVERSION_ERROR;
 
     static FileSpec::PathSyntax GetNativePathSyntax();
 
@@ -59,6 +62,15 @@ class FileSystem
 
     /// Return \b true if \a spec is on a locally mounted file system, \b false otherwise.
     static bool IsLocal(const FileSpec &spec);
+
+    /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be
+    /// manipulated and closed with the normal ::fread, ::fclose, etc. functions.
+    static FILE *
+    Fopen(const char *path, const char *mode);
+
+    /// Wraps ::stat in a platform-independent way.
+    static int
+    Stat(const char *path, struct stat *stats);
 };
 }
 

Modified: lldb/trunk/include/lldb/Host/posix/HostInfoPosix.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/posix/HostInfoPosix.h?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/posix/HostInfoPosix.h (original)
+++ lldb/trunk/include/lldb/Host/posix/HostInfoPosix.h Tue Mar 22 12:58:09 2016
@@ -33,7 +33,10 @@ class HostInfoPosix : public HostInfoBas
 
     static FileSpec GetDefaultShell();
 
-  protected:
+    static bool
+    GetEnvironmentVar(const std::string &var_name, std::string &var);
+
+protected:
     static bool ComputeSupportExeDirectory(FileSpec &file_spec);
     static bool ComputeHeaderDirectory(FileSpec &file_spec);
     static bool ComputePythonDirectory(FileSpec &file_spec);

Modified: lldb/trunk/include/lldb/Host/windows/HostInfoWindows.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/windows/HostInfoWindows.h?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Host/windows/HostInfoWindows.h (original)
+++ lldb/trunk/include/lldb/Host/windows/HostInfoWindows.h Tue Mar 22 12:58:09 2016
@@ -47,6 +47,9 @@ class HostInfoWindows : public HostInfoB
       static FileSpec
       GetDefaultShell();
 
+      static bool
+      GetEnvironmentVar(const std::string &var_name, std::string &var);
+
   protected:
     static bool ComputePythonDirectory(FileSpec &file_spec);
 

Modified: lldb/trunk/packages/Python/lldbsuite/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/dotest.py?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/dotest.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/dotest.py Tue Mar 22 12:58:09 2016
@@ -659,7 +659,7 @@ def setupSysPath():
                 print("     location of LLDB\'s site-packages folder.")
                 print("  3) A different version of Python than that which was built against is exported in")
                 print("     the system\'s PATH environment variable, causing conflicts.")
-                print("  4) The executable '%s' could not be found.  Please check " % lldbExecutable)
+                print("  4) The executable '%s' could not be found.  Please check " % lldbtest_config.lldbExec)
                 print("     that it exists and is executable.")
 
     if lldbPythonDir:

Modified: lldb/trunk/source/Commands/CommandCompletions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandCompletions.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandCompletions.cpp (original)
+++ lldb/trunk/source/Commands/CommandCompletions.cpp Tue Mar 22 12:58:09 2016
@@ -18,10 +18,11 @@
 #include "llvm/ADT/SmallString.h"
 
 // Project includes
-#include "lldb/Host/FileSpec.h"
 #include "lldb/Core/FileSpecList.h"
-#include "lldb/Core/PluginManager.h"
 #include "lldb/Core/Module.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Interpreter/CommandCompletions.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
@@ -31,6 +32,8 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/CleanUp.h"
 
+#include "llvm/ADT/SmallString.h"
+
 using namespace lldb_private;
 
 CommandCompletions::CommonCompletionElement
@@ -160,8 +163,7 @@ FileSpec::EnumerateDirectoryResult DiskF
             isa_directory = true;
         else if (file_type == FileSpec::eFileTypeSymbolicLink)
         {
-            struct stat stat_buf;
-            if ((stat(partial_name_copy, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode))
+            if (FileSpec(partial_name_copy, false).IsDirectory())
                 isa_directory = true;
         }
 

Modified: lldb/trunk/source/Core/ConnectionSharedMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionSharedMemory.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionSharedMemory.cpp (original)
+++ lldb/trunk/source/Core/ConnectionSharedMemory.cpp Tue Mar 22 12:58:09 2016
@@ -32,6 +32,8 @@
 #include "lldb/Core/Communication.h"
 #include "lldb/Core/Log.h"
 
+#include "llvm/Support/ConvertUTF.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -135,18 +137,18 @@ ConnectionSharedMemory::Open (bool creat
     m_name.assign (name);
 
 #ifdef _WIN32
-    HANDLE handle;
-    if (create) {
-        handle = CreateFileMapping(
-            INVALID_HANDLE_VALUE,
-            nullptr,
-            PAGE_READWRITE,
-            llvm::Hi_32(size),
-            llvm::Lo_32(size),
-            name);
+    HANDLE handle = INVALID_HANDLE_VALUE;
+    std::wstring wname;
+    if (llvm::ConvertUTF8toWide(name, wname))
+    {
+        if (create)
+        {
+            handle = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, llvm::Hi_32(size),
+                                        llvm::Lo_32(size), wname.c_str());
+        }
+        else
+            handle = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, wname.c_str());
     }
-    else
-        handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, name);
 
     m_fd = _open_osfhandle((intptr_t)handle, 0);
 #else

Modified: lldb/trunk/source/Core/Disassembler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Disassembler.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Core/Disassembler.cpp (original)
+++ lldb/trunk/source/Core/Disassembler.cpp Tue Mar 22 12:58:09 2016
@@ -16,16 +16,16 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/lldb-private.h"
-#include "lldb/Core/Error.h"
 #include "lldb/Core/DataBufferHeap.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Core/Error.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/PluginManager.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Interpreter/OptionValue.h"
 #include "lldb/Interpreter/OptionValueArray.h"
 #include "lldb/Interpreter/OptionValueDictionary.h"
@@ -38,6 +38,7 @@
 #include "lldb/Target/SectionLoadList.h"
 #include "lldb/Target/StackFrame.h"
 #include "lldb/Target/Target.h"
+#include "lldb/lldb-private.h"
 
 #define DEFAULT_DISASM_BYTE_SIZE 32
 
@@ -849,8 +850,7 @@ Instruction::TestEmulation (Stream *out_
         out_stream->Printf ("Instruction::TestEmulation:  Missing file_name.");
         return false;
     }
-        
-    FILE *test_file = fopen (file_name, "r");
+    FILE *test_file = FileSystem::Fopen(file_name, "r");
     if (!test_file)
     {
         out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");

Modified: lldb/trunk/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/File.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/File.cpp (original)
+++ lldb/trunk/source/Host/common/File.cpp Tue Mar 22 12:58:09 2016
@@ -14,7 +14,6 @@
 #include <limits.h>
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/stat.h>
 
 #ifdef _WIN32
 #include "lldb/Host/windows/windows.h"
@@ -22,6 +21,7 @@
 #include <sys/ioctl.h>
 #endif
 
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
 
 #include "lldb/Core/DataBufferHeap.h"
@@ -29,6 +29,7 @@
 #include "lldb/Core/Log.h"
 #include "lldb/Host/Config.h"
 #include "lldb/Host/FileSpec.h"
+#include "lldb/Host/FileSystem.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -267,7 +268,18 @@ File::Open (const char *path, uint32_t o
 
     do
     {
+#ifdef _WIN32
+        std::wstring wpath;
+        if (!llvm::ConvertUTF8toWide(path, wpath))
+        {
+            m_descriptor = -1;
+            error.SetErrorString("Error converting path to UTF-16");
+            return error;
+        }
+        ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
+#else
         m_descriptor = ::open(path, oflag, mode);
+#endif
     } while (m_descriptor < 0 && errno == EINTR);
 
     if (!DescriptorIsValid())
@@ -287,7 +299,8 @@ File::GetPermissions(const FileSpec &fil
     if (file_spec)
     {
         struct stat file_stats;
-        if (::stat(file_spec.GetCString(), &file_stats) == -1)
+        int stat_result = FileSystem::Stat(file_spec.GetCString(), &file_stats);
+        if (stat_result == -1)
             error.SetErrorToErrno();
         else
         {

Modified: lldb/trunk/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/FileSpec.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/FileSpec.cpp (original)
+++ lldb/trunk/source/Host/common/FileSpec.cpp Tue Mar 22 12:58:09 2016
@@ -17,7 +17,6 @@
 #ifndef _MSC_VER
 #include <libgen.h>
 #endif
-#include <sys/stat.h>
 #include <set>
 #include <string.h>
 #include <fstream>
@@ -40,6 +39,7 @@
 #include "lldb/Utility/CleanUp.h"
 
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Program.h"
@@ -90,7 +90,7 @@ GetFileStats (const FileSpec *file_spec,
 {
     char resolved_path[PATH_MAX];
     if (file_spec->GetPath (resolved_path, sizeof(resolved_path)))
-        return ::stat (resolved_path, stats_ptr) == 0;
+        return FileSystem::Stat(resolved_path, stats_ptr) == 0;
     return false;
 }
 
@@ -206,15 +206,10 @@ FileSpec::Resolve (llvm::SmallVectorImpl
 #endif // #ifdef LLDB_CONFIG_TILDE_RESOLVES_TO_USER
 
     // Save a copy of the original path that's passed in
-    llvm::SmallString<PATH_MAX> original_path(path.begin(), path.end());
+    llvm::SmallString<128> original_path(path.begin(), path.end());
 
     llvm::sys::fs::make_absolute(path);
-
-    
-    path.push_back(0);  // Be sure we have a nul terminated string
-    path.pop_back();
-    struct stat file_stats;
-    if (::stat (path.data(), &file_stats) != 0)
+    if (!llvm::sys::fs::exists(path))
     {
         path.clear();
         path.append(original_path.begin(), original_path.end());
@@ -815,7 +810,10 @@ FileSpec::IsSymbolicLink () const
         return false;
 
 #ifdef _WIN32
-    auto attrs = ::GetFileAttributes (resolved_path);
+    std::wstring wpath;
+    if (!llvm::ConvertUTF8toWide(resolved_path, wpath))
+        return false;
+    auto attrs = ::GetFileAttributesW(wpath.c_str());
     if (attrs == INVALID_FILE_ATTRIBUTES)
         return false;
 
@@ -1114,12 +1112,18 @@ FileSpec::ForEachItemInDirectory (const
 {
     if (dir_path && dir_path[0])
     {
-#if _WIN32
+#ifdef _WIN32
         std::string szDir(dir_path);
         szDir += "\\*";
 
-        WIN32_FIND_DATA ffd;
-        HANDLE hFind = FindFirstFile(szDir.c_str(), &ffd);
+        std::wstring wszDir;
+        if (!llvm::ConvertUTF8toWide(szDir, wszDir))
+        {
+            return eEnumerateDirectoryResultNext;
+        }
+
+        WIN32_FIND_DATAW ffd;
+        HANDLE hFind = FindFirstFileW(wszDir.c_str(), &ffd);
 
         if (hFind == INVALID_HANDLE_VALUE)
         {
@@ -1131,12 +1135,12 @@ FileSpec::ForEachItemInDirectory (const
             FileSpec::FileType file_type = eFileTypeUnknown;
             if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
             {
-                size_t len = strlen(ffd.cFileName);
+                size_t len = wcslen(ffd.cFileName);
 
-                if (len == 1 && ffd.cFileName[0] == '.')
+                if (len == 1 && ffd.cFileName[0] == L'.')
                     continue;
 
-                if (len == 2 && ffd.cFileName[0] == '.' && ffd.cFileName[1] == '.')
+                if (len == 2 && ffd.cFileName[0] == L'.' && ffd.cFileName[1] == L'.')
                     continue;
 
                 file_type = eFileTypeDirectory;
@@ -1150,12 +1154,19 @@ FileSpec::ForEachItemInDirectory (const
                 file_type = eFileTypeRegular;
             }
 
-            char child_path[MAX_PATH];
-            const int child_path_len = ::snprintf (child_path, sizeof(child_path), "%s\\%s", dir_path, ffd.cFileName);
-            if (child_path_len < (int)(sizeof(child_path) - 1))
+            std::string fileName;
+            if (!llvm::convertWideToUTF8(ffd.cFileName, fileName))
+            {
+                continue;
+            }
+
+            std::vector<char> child_path(PATH_MAX);
+            const int child_path_len =
+                ::snprintf(child_path.data(), child_path.size(), "%s\\%s", dir_path, fileName.c_str());
+            if (child_path_len < (int)(child_path.size() - 1))
             {
                 // Don't resolve the file type or path
-                FileSpec child_path_spec (child_path, false);
+                FileSpec child_path_spec(child_path.data(), false);
 
                 EnumerateDirectoryResult result = callback (file_type, child_path_spec);
 
@@ -1168,7 +1179,8 @@ FileSpec::ForEachItemInDirectory (const
                         break;
 
                     case eEnumerateDirectoryResultEnter: // Recurse into the current entry if it is a directory or symlink, or next if not
-                        if (FileSpec::ForEachItemInDirectory(child_path, callback) == eEnumerateDirectoryResultQuit)
+                        if (FileSpec::ForEachItemInDirectory(child_path.data(), callback) ==
+                            eEnumerateDirectoryResultQuit)
                         {
                             // The subdirectory returned Quit, which means to
                             // stop all directory enumerations at all levels.
@@ -1185,7 +1197,7 @@ FileSpec::ForEachItemInDirectory (const
                         return eEnumerateDirectoryResultQuit;
                 }
             }
-        } while (FindNextFile(hFind, &ffd) != 0);
+        } while (FindNextFileW(hFind, &ffd) != 0);
 
         FindClose(hFind);
 #else

Modified: lldb/trunk/source/Host/posix/FileSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/FileSystem.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/FileSystem.cpp (original)
+++ lldb/trunk/source/Host/posix/FileSystem.cpp Tue Mar 22 12:58:09 2016
@@ -299,3 +299,15 @@ FileSystem::IsLocal(const FileSpec &spec
     return false;
 }
 #endif
+
+FILE *
+FileSystem::Fopen(const char *path, const char *mode)
+{
+    return ::fopen(path, mode);
+}
+
+int
+FileSystem::Stat(const char *path, struct stat *stats)
+{
+    return ::stat(path, stats);
+}

Modified: lldb/trunk/source/Host/posix/HostInfoPosix.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/posix/HostInfoPosix.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/posix/HostInfoPosix.cpp (original)
+++ lldb/trunk/source/Host/posix/HostInfoPosix.cpp Tue Mar 22 12:58:09 2016
@@ -242,3 +242,14 @@ HostInfoPosix::ComputePythonDirectory(Fi
     return false;
 #endif
 }
+
+bool
+HostInfoPosix::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+    if (const char *pvar = ::getenv(var_name.c_str()))
+    {
+        var = std::string(pvar);
+        return true;
+    }
+    return false;
+}

Modified: lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/ConnectionGenericFileWindows.cpp Tue Mar 22 12:58:09 2016
@@ -14,6 +14,7 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ConvertUTF.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -138,7 +139,15 @@ ConnectionGenericFile::Connect(const cha
     // Open the file for overlapped access.  If it does not exist, create it.  We open it overlapped
     // so that we can issue asynchronous reads and then use WaitForMultipleObjects to allow the read
     // to be interrupted by an event object.
-    m_file = ::CreateFile(path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_FLAG_OVERLAPPED, NULL);
+    std::wstring wpath;
+    if (!llvm::ConvertUTF8toWide(path, wpath))
+    {
+        if (error_ptr)
+            error_ptr->SetError(1, eErrorTypeGeneric);
+        return eConnectionStatusError;
+    }
+    m_file = ::CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS,
+                           FILE_FLAG_OVERLAPPED, NULL);
     if (m_file == INVALID_HANDLE_VALUE)
     {
         if (error_ptr)

Modified: lldb/trunk/source/Host/windows/FileSystem.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/FileSystem.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/FileSystem.cpp (original)
+++ lldb/trunk/source/Host/windows/FileSystem.cpp Tue Mar 22 12:58:09 2016
@@ -15,6 +15,8 @@
 
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/windows/AutoHandle.h"
+
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/FileSystem.h"
 
 using namespace lldb_private;
@@ -22,6 +24,8 @@ using namespace lldb_private;
 const char *
 FileSystem::DEV_NULL = "nul";
 
+const char *FileSystem::PATH_CONVERSION_ERROR = "Error converting path between UTF-8 and native encoding";
+
 FileSpec::PathSyntax
 FileSystem::GetNativePathSyntax()
 {
@@ -47,25 +51,32 @@ Error
 FileSystem::DeleteDirectory(const FileSpec &file_spec, bool recurse)
 {
     Error error;
+    std::wstring path_buffer;
+    if (!llvm::ConvertUTF8toWide(file_spec.GetPath(), path_buffer))
+    {
+        error.SetErrorString(PATH_CONVERSION_ERROR);
+        return error;
+    }
     if (!recurse)
     {
-        BOOL result = ::RemoveDirectory(file_spec.GetCString());
+        BOOL result = ::RemoveDirectoryW(path_buffer.c_str());
         if (!result)
             error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
     }
     else
     {
         // SHFileOperation() accepts a list of paths, and so must be double-null-terminated to
-        // indicate the end of the list.
-        std::string path_buffer{file_spec.GetPath()};
+        // indicate the end of the list. The first null terminator is there only in the backing
+        // store but not the actual vector contents, and so we need to push twice.
+        path_buffer.push_back(0);
         path_buffer.push_back(0);
 
-        SHFILEOPSTRUCT shfos = {0};
+        SHFILEOPSTRUCTW shfos = {0};
         shfos.wFunc = FO_DELETE;
-        shfos.pFrom = path_buffer.c_str();
+        shfos.pFrom = (LPCWSTR)path_buffer.data();
         shfos.fFlags = FOF_NO_UI;
 
-        int result = ::SHFileOperation(&shfos);
+        int result = ::SHFileOperationW(&shfos);
         // TODO(zturner): Correctly handle the intricacies of SHFileOperation return values.
         if (result != 0)
             error.SetErrorStringWithFormat("SHFileOperation failed");
@@ -121,7 +132,10 @@ Error
 FileSystem::Hardlink(const FileSpec &src, const FileSpec &dst)
 {
     Error error;
-    if (!::CreateHardLink(src.GetCString(), dst.GetCString(), nullptr))
+    std::wstring wsrc, wdst;
+    if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+        error.SetErrorString(PATH_CONVERSION_ERROR);
+    else if (!::CreateHardLinkW(wsrc.c_str(), wdst.c_str(), nullptr))
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
     return error;
 }
@@ -129,13 +143,12 @@ FileSystem::Hardlink(const FileSpec &src
 int
 FileSystem::GetHardlinkCount(const FileSpec &file_spec)
 {
-    HANDLE file_handle = ::CreateFile(file_spec.GetCString(),
-                                      FILE_READ_ATTRIBUTES,
-                                      FILE_SHARE_READ,
-                                      nullptr,
-                                      OPEN_EXISTING,
-                                      FILE_ATTRIBUTE_NORMAL,
-                                      nullptr);
+    std::wstring path;
+    if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+        return -1;
+
+    HANDLE file_handle = ::CreateFileW(path.c_str(), FILE_READ_ATTRIBUTES, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
+                                       FILE_ATTRIBUTE_NORMAL, nullptr);
 
     if (file_handle == INVALID_HANDLE_VALUE)
       return -1;
@@ -152,7 +165,12 @@ Error
 FileSystem::Symlink(const FileSpec &src, const FileSpec &dst)
 {
     Error error;
-    DWORD attrib = ::GetFileAttributes(dst.GetCString());
+    std::wstring wsrc, wdst;
+    if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc) || !llvm::ConvertUTF8toWide(dst.GetCString(), wdst))
+        error.SetErrorString(PATH_CONVERSION_ERROR);
+    if (error.Fail())
+        return error;
+    DWORD attrib = ::GetFileAttributesW(wdst.c_str());
     if (attrib == INVALID_FILE_ATTRIBUTES)
     {
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@@ -160,7 +178,7 @@ FileSystem::Symlink(const FileSpec &src,
     }
     bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
     DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
-    BOOL result = ::CreateSymbolicLink(src.GetCString(), dst.GetCString(), flag);
+    BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
     if (!result)
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
     return error;
@@ -170,7 +188,13 @@ Error
 FileSystem::Unlink(const FileSpec &file_spec)
 {
     Error error;
-    BOOL result = ::DeleteFile(file_spec.GetCString());
+    std::wstring path;
+    if (!llvm::ConvertUTF8toWide(file_spec.GetCString(), path))
+    {
+        error.SetErrorString(PATH_CONVERSION_ERROR);
+        return error;
+    }
+    BOOL result = ::DeleteFileW(path.c_str());
     if (!result)
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
     return error;
@@ -180,23 +204,31 @@ Error
 FileSystem::Readlink(const FileSpec &src, FileSpec &dst)
 {
     Error error;
-    HANDLE h = ::CreateFile(src.GetCString(), GENERIC_READ,
-            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
-            FILE_FLAG_OPEN_REPARSE_POINT, NULL);
+    std::wstring wsrc;
+    if (!llvm::ConvertUTF8toWide(src.GetCString(), wsrc))
+    {
+        error.SetErrorString(PATH_CONVERSION_ERROR);
+        return error;
+    }
+
+    HANDLE h = ::CreateFileW(wsrc.c_str(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
+                             FILE_FLAG_OPEN_REPARSE_POINT, NULL);
     if (h == INVALID_HANDLE_VALUE)
     {
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
         return error;
     }
 
-    char buf[PATH_MAX];
+    std::vector<wchar_t> buf(PATH_MAX + 1);
     // Subtract 1 from the path length since this function does not add a null terminator.
-    DWORD result = ::GetFinalPathNameByHandle(h, buf, sizeof(buf) - 1,
-            FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    DWORD result = ::GetFinalPathNameByHandleW(h, buf.data(), buf.size() - 1, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
+    std::string path;
     if (result == 0)
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
+    else if (!llvm::convertWideToUTF8(buf.data(), path))
+        error.SetErrorString(PATH_CONVERSION_ERROR);
     else
-        dst.SetFile(buf, false);
+        dst.SetFile(path, false);
 
     ::CloseHandle(h);
     return error;
@@ -219,3 +251,43 @@ FileSystem::IsLocal(const FileSpec &spec
 
     return false;
 }
+
+FILE *
+FileSystem::Fopen(const char *path, const char *mode)
+{
+    std::wstring wpath, wmode;
+    if (!llvm::ConvertUTF8toWide(path, wpath))
+        return nullptr;
+    if (!llvm::ConvertUTF8toWide(mode, wmode))
+        return nullptr;
+    FILE *file;
+    if (_wfopen_s(&file, wpath.c_str(), wmode.c_str()) != 0)
+        return nullptr;
+    return file;
+}
+
+int
+FileSystem::Stat(const char *path, struct stat *stats)
+{
+    std::wstring wpath;
+    if (!llvm::ConvertUTF8toWide(path, wpath))
+    {
+        errno = EINVAL;
+        return -EINVAL;
+    }
+    int stat_result;
+#ifdef _USE_32BIT_TIME_T
+    struct _stat32 file_stats;
+    stat_result = ::_wstat32(wpath.c_str(), &file_stats);
+#else
+    struct _stat64i32 file_stats;
+    stat_result = ::_wstat64i32(wpath.c_str(), &file_stats);
+#endif
+    if (stat_result == 0)
+    {
+        static_assert(sizeof(struct stat) == sizeof(file_stats),
+                      "stat and _stat32/_stat64i32 must have the same layout");
+        *stats = *reinterpret_cast<struct stat *>(&file_stats);
+    }
+    return stat_result;
+}

Modified: lldb/trunk/source/Host/windows/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/Host.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/Host.cpp (original)
+++ lldb/trunk/source/Host/windows/Host.cpp Tue Mar 22 12:58:09 2016
@@ -26,6 +26,8 @@
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StructuredData.h"
 
+#include "llvm/Support/ConvertUTF.h"
+
 // Windows includes
 #include <TlHelp32.h>
 
@@ -68,12 +70,11 @@ namespace
     bool GetExecutableForProcess(const AutoHandle &handle, std::string &path)
     {
         // Get the process image path.  MAX_PATH isn't long enough, paths can actually be up to 32KB.
-        std::vector<char> buffer(32768);
+        std::vector<wchar_t> buffer(PATH_MAX);
         DWORD dwSize = buffer.size();
-        if (!::QueryFullProcessImageNameA(handle.get(), 0, &buffer[0], &dwSize))
+        if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
             return false;
-        path.assign(&buffer[0]);
-        return true;
+        return llvm::convertWideToUTF8(buffer.data(), path);
     }
 
     void GetProcessExecutableAndTriple(const AutoHandle &handle, ProcessInstanceInfo &process)
@@ -156,15 +157,17 @@ Host::GetModuleFileSpecForHostAddress (c
     if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)host_addr, &hmodule))
         return module_filespec;
 
-    std::vector<char> buffer(MAX_PATH);
+    std::vector<wchar_t> buffer(PATH_MAX);
     DWORD chars_copied = 0;
     do {
-        chars_copied = ::GetModuleFileName(hmodule, &buffer[0], buffer.size());
+        chars_copied = ::GetModuleFileNameW(hmodule, &buffer[0], buffer.size());
         if (chars_copied == buffer.size() && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
             buffer.resize(buffer.size() * 2);
     } while (chars_copied >= buffer.size());
-
-    module_filespec.SetFile(&buffer[0], false);
+    std::string path;
+    if (!llvm::convertWideToUTF8(buffer.data(), path))
+        return module_filespec;
+    module_filespec.SetFile(path, false);
     return module_filespec;
 }
 
@@ -177,23 +180,25 @@ Host::FindProcesses (const ProcessInstan
     if (!snapshot.IsValid())
         return 0;
 
-    PROCESSENTRY32 pe = {0};
-    pe.dwSize = sizeof(PROCESSENTRY32);
-    if (Process32First(snapshot.get(), &pe))
+    PROCESSENTRY32W pe = {0};
+    pe.dwSize = sizeof(PROCESSENTRY32W);
+    if (Process32FirstW(snapshot.get(), &pe))
     {
         do
         {
             AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pe.th32ProcessID), nullptr);
 
             ProcessInstanceInfo process;
-            process.SetExecutableFile(FileSpec(pe.szExeFile, false), true);
+            std::string exeFile;
+            llvm::convertWideToUTF8(pe.szExeFile, exeFile);
+            process.SetExecutableFile(FileSpec(exeFile, false), true);
             process.SetProcessID(pe.th32ProcessID);
             process.SetParentProcessID(pe.th32ParentProcessID);
             GetProcessExecutableAndTriple(handle, process);
 
             if (match_info.MatchAllProcesses() || match_info.Matches(process))
                 process_infos.Append(process);
-        } while (Process32Next(snapshot.get(), &pe));
+        } while (Process32NextW(snapshot.get(), &pe));
     }
     return process_infos.GetSize();
 }
@@ -312,15 +317,21 @@ Host::GetEnvironment(StringList &env)
 {
     // The environment block on Windows is a contiguous buffer of NULL terminated strings,
     // where the end of the environment block is indicated by two consecutive NULLs.
-    LPCH environment_block = ::GetEnvironmentStrings();
+    LPWCH environment_block = ::GetEnvironmentStringsW();
     env.Clear();
-    while (*environment_block != '\0')
+    while (*environment_block != L'\0')
     {
-        llvm::StringRef current_var(environment_block);
+        std::string current_var;
+        auto current_var_size = wcslen(environment_block) + 1;
+        if (!llvm::convertWideToUTF8(environment_block, current_var))
+        {
+            environment_block += current_var_size;
+            continue;
+        }
         if (current_var[0] != '=')
             env.AppendString(current_var);
 
-        environment_block += current_var.size()+1;
+        environment_block += current_var_size;
     }
     return env.GetSize();
 }

Modified: lldb/trunk/source/Host/windows/HostInfoWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/HostInfoWindows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/HostInfoWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/HostInfoWindows.cpp Tue Mar 22 12:58:09 2016
@@ -15,9 +15,10 @@
 
 #include "lldb/Host/windows/HostInfoWindows.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/FileSystem.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
 
 using namespace lldb_private;
 
@@ -92,23 +93,24 @@ HostInfoWindows::GetOSKernelDescription(
 bool
 HostInfoWindows::GetHostname(std::string &s)
 {
-    char buffer[MAX_COMPUTERNAME_LENGTH + 1];
+    wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
-    if (!::GetComputerName(buffer, &dwSize))
+    if (!::GetComputerNameW(buffer, &dwSize))
         return false;
 
-    s.assign(buffer, buffer + dwSize);
-    return true;
+    return llvm::convertWideToUTF8(buffer, s);
 }
 
 FileSpec
 HostInfoWindows::GetProgramFileSpec()
 {
     static std::once_flag g_once_flag;
-    std::call_once(g_once_flag,  []() {
-        char buffer[PATH_MAX];
-        ::GetModuleFileName(NULL, buffer, sizeof(buffer));
-        m_program_filespec.SetFile(buffer, false);
+    std::call_once(g_once_flag, []() {
+        std::vector<wchar_t> buffer(PATH_MAX);
+        ::GetModuleFileNameW(NULL, buffer.data(), buffer.size());
+        std::string path;
+        llvm::convertWideToUTF8(buffer.data(), path);
+        m_program_filespec.SetFile(path, false);
     });
     return m_program_filespec;
 }
@@ -116,7 +118,9 @@ HostInfoWindows::GetProgramFileSpec()
 FileSpec
 HostInfoWindows::GetDefaultShell()
 {
-    return FileSpec(::getenv("ComSpec"), false);
+    std::string shell;
+    GetEnvironmentVar("ComSpec", shell);
+    return FileSpec(shell, false);
 }
 
 bool
@@ -132,3 +136,15 @@ HostInfoWindows::ComputePythonDirectory(
     file_spec.GetDirectory().SetString(path.c_str());
     return true;
 }
+
+bool
+HostInfoWindows::GetEnvironmentVar(const std::string &var_name, std::string &var)
+{
+    std::wstring wvar_name;
+    if (!llvm::ConvertUTF8toWide(var_name, wvar_name))
+        return false;
+
+    if (const wchar_t *wvar = _wgetenv(wvar_name.c_str()))
+        return llvm::convertWideToUTF8(wvar, var);
+    return false;
+}

Modified: lldb/trunk/source/Host/windows/HostProcessWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/HostProcessWindows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/HostProcessWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/HostProcessWindows.cpp Tue Mar 22 12:58:09 2016
@@ -14,6 +14,7 @@
 #include "lldb/Host/windows/HostProcessWindows.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
 
 #include <Psapi.h>
 
@@ -70,9 +71,15 @@ Error HostProcessWindows::GetMainModule(
     if (m_process == nullptr)
         error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
 
-    char path[MAX_PATH] = { 0 };
-    if (::GetProcessImageFileName(m_process, path, llvm::array_lengthof(path)))
-        file_spec.SetFile(path, false);
+    std::vector<wchar_t> wpath(PATH_MAX);
+    if (::GetProcessImageFileNameW(m_process, wpath.data(), wpath.size()))
+    {
+        std::string path;
+        if (llvm::convertWideToUTF8(wpath.data(), path))
+            file_spec.SetFile(path, false);
+        else
+            error.SetErrorString("Error converting path to UTF-8");
+    }
     else
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
 

Modified: lldb/trunk/source/Host/windows/PipeWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/PipeWindows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/PipeWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/PipeWindows.cpp Tue Mar 22 12:58:09 2016
@@ -73,8 +73,8 @@ PipeWindows::CreateNew(llvm::StringRef n
 
     // Always open for overlapped i/o.  We implement blocking manually in Read and Write.
     DWORD read_mode = FILE_FLAG_OVERLAPPED;
-    m_read =
-        ::CreateNamedPipe(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024, 1024, 120 * 1000, NULL);
+    m_read = ::CreateNamedPipeA(pipe_path.c_str(), PIPE_ACCESS_INBOUND | read_mode, PIPE_TYPE_BYTE | PIPE_WAIT, 1, 1024,
+                                1024, 120 * 1000, NULL);
     if (INVALID_HANDLE_VALUE == m_read)
         return Error(::GetLastError(), eErrorTypeWin32);
     m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
@@ -153,7 +153,8 @@ PipeWindows::OpenNamedPipe(llvm::StringR
 
     if (is_read)
     {
-        m_read = ::CreateFile(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+        m_read =
+            ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
         if (INVALID_HANDLE_VALUE == m_read)
             return Error(::GetLastError(), eErrorTypeWin32);
 
@@ -164,7 +165,8 @@ PipeWindows::OpenNamedPipe(llvm::StringR
     }
     else
     {
-        m_write = ::CreateFile(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
+        m_write =
+            ::CreateFileA(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
         if (INVALID_HANDLE_VALUE == m_write)
             return Error(::GetLastError(), eErrorTypeWin32);
 

Modified: lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp (original)
+++ lldb/trunk/source/Host/windows/ProcessLauncherWindows.cpp Tue Mar 22 12:58:09 2016
@@ -11,6 +11,9 @@
 #include "lldb/Host/windows/ProcessLauncherWindows.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
 
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ConvertUTF.h"
+
 #include <string>
 #include <vector>
 
@@ -25,20 +28,18 @@ CreateEnvironmentBuffer(const Args &env,
     if (env.GetArgumentCount() == 0)
         return;
 
-    int bytes = 0;
-    for (int i = 0; i < env.GetArgumentCount(); ++i)
-        bytes += strlen(env.GetArgumentAtIndex(i)) + sizeof(char);
-    bytes += sizeof(char);
-    buffer.resize(bytes);
-    char *cur_entry = &buffer[0];
+    // Environment buffer is a null terminated list of null terminated strings
     for (int i = 0; i < env.GetArgumentCount(); ++i)
     {
-        ::strcpy(cur_entry, env.GetArgumentAtIndex(i));
-        cur_entry += strlen(cur_entry) + sizeof(char);
+        std::wstring warg;
+        if (llvm::ConvertUTF8toWide(env.GetArgumentAtIndex(i), warg))
+        {
+            buffer.insert(buffer.end(), (char *)warg.c_str(), (char *)(warg.c_str() + warg.size() + 1));
+        }
     }
-    // Environment buffer is a null terminated list of null terminated
-    // strings, so it is terminated by two null bytes.
-    buffer.back() = 0;
+    // One null wchar_t (to end the block) is two null bytes
+    buffer.push_back(0);
+    buffer.push_back(0);
 }
 }
 
@@ -70,7 +71,7 @@ ProcessLauncherWindows::LaunchProcess(co
         startupinfo.wShowWindow = SW_HIDE;
     }
 
-    DWORD flags = CREATE_NEW_CONSOLE;
+    DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
     if (launch_info.GetFlags().Test(eLaunchFlagDebug))
         flags |= DEBUG_ONLY_THIS_PROCESS;
 
@@ -82,8 +83,15 @@ ProcessLauncherWindows::LaunchProcess(co
 
     executable = launch_info.GetExecutableFile().GetPath();
     launch_info.GetArguments().GetQuotedCommandString(commandLine);
-    BOOL result = ::CreateProcessA(executable.c_str(), const_cast<char *>(commandLine.c_str()), NULL, NULL, TRUE, flags,
-                                   env_block, launch_info.GetWorkingDirectory().GetCString(), &startupinfo, &pi);
+
+    std::wstring wexecutable, wcommandLine, wworkingDirectory;
+    llvm::ConvertUTF8toWide(executable, wexecutable);
+    llvm::ConvertUTF8toWide(commandLine, wcommandLine);
+    llvm::ConvertUTF8toWide(launch_info.GetWorkingDirectory().GetCString(), wworkingDirectory);
+
+    wcommandLine.resize(PATH_MAX); // Needs to be over-allocated because CreateProcessW can modify it
+    BOOL result = ::CreateProcessW(wexecutable.c_str(), &wcommandLine[0], NULL, NULL, TRUE, flags, env_block,
+                                   wworkingDirectory.size() == 0 ? NULL : wworkingDirectory.c_str(), &startupinfo, &pi);
     if (result)
     {
         // Do not call CloseHandle on pi.hProcess, since we want to pass that back through the HostProcess.
@@ -131,6 +139,8 @@ ProcessLauncherWindows::GetStdioHandle(c
             flags = FILE_FLAG_WRITE_THROUGH;
     }
 
-    HANDLE result = ::CreateFile(path, access, share, &secattr, create, flags, NULL);
+    std::wstring wpath;
+    llvm::ConvertUTF8toWide(path, wpath);
+    HANDLE result = ::CreateFileW(wpath.c_str(), access, share, &secattr, create, flags, NULL);
     return (result == INVALID_HANDLE_VALUE) ? NULL : result;
 }

Modified: lldb/trunk/source/Host/windows/Windows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/windows/Windows.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Host/windows/Windows.cpp (original)
+++ lldb/trunk/source/Host/windows/Windows.cpp Tue Mar 22 12:58:09 2016
@@ -12,6 +12,8 @@
 #include "lldb/Host/windows/windows.h"
 #include "lldb/Host/windows/win32.h"
 
+#include "llvm/Support/ConvertUTF.h"
+
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
@@ -27,6 +29,29 @@ extern "C"
     int _chdir(const char *path);
 }
 
+namespace
+{
+bool
+utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize)
+{
+    const UTF8 *sourceStart = reinterpret_cast<const UTF8 *>(utf8);
+    size_t sourceLen = strlen(utf8) + 1 /* convert null too */;
+    UTF16 *target = reinterpret_cast<UTF16 *>(buf);
+    ConversionFlags flags = strictConversion;
+    return ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK;
+}
+
+bool
+wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize)
+{
+    const UTF16 *sourceStart = reinterpret_cast<const UTF16 *>(wide);
+    size_t sourceLen = wcslen(wide) + 1 /* convert null too */;
+    UTF8 *target = reinterpret_cast<UTF8 *>(buf);
+    ConversionFlags flags = strictConversion;
+    return ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target, target + bufSize, flags) == conversionOK;
+}
+}
+
 int vasprintf(char **ret, const char *fmt, va_list ap)
 {
     char *buf;
@@ -75,81 +100,90 @@ char* strcasestr(const char *s, const ch
 
 char* realpath(const char * name, char * resolved)
 {
-    char *retname = NULL;  /* we will return this, if we fail */
+    char *retname = NULL;
 
     /* SUSv3 says we must set `errno = EINVAL', and return NULL,
     * if `name' is passed as a NULL pointer.
     */
-
     if (name == NULL)
+    {
         errno = EINVAL;
+        return NULL;
+    }
 
     /* Otherwise, `name' must refer to a readable filesystem object,
     * if we are going to resolve its absolute path name.
     */
-
-    else if (access(name, 4) == 0)
+    wchar_t wideNameBuffer[PATH_MAX];
+    wchar_t *wideName = wideNameBuffer;
+    if (!utf8ToWide(name, wideName, PATH_MAX))
     {
-        /* If `name' didn't point to an existing entity,
-        * then we don't get to here; we simply fall past this block,
-        * returning NULL, with `errno' appropriately set by `access'.
-        *
-        * When we _do_ get to here, then we can use `_fullpath' to
-        * resolve the full path for `name' into `resolved', but first,
-        * check that we have a suitable buffer, in which to return it.
-        */
+        errno = EINVAL;
+        return NULL;
+    }
 
-        if ((retname = resolved) == NULL)
-        {
-            /* Caller didn't give us a buffer, so we'll exercise the
-            * option granted by SUSv3, and allocate one.
-            *
-            * `_fullpath' would do this for us, but it uses `malloc', and
-            * Microsoft's implementation doesn't set `errno' on failure.
-            * If we don't do this explicitly ourselves, then we will not
-            * know if `_fullpath' fails on `malloc' failure, or for some
-            * other reason, and we want to set `errno = ENOMEM' for the
-            * `malloc' failure case.
-            */
+    if (_waccess(wideName, 4) != 0)
+        return NULL;
 
-            retname = (char*) malloc(_MAX_PATH);
-        }
+    /* If `name' didn't point to an existing entity,
+    * then we don't get to here; we simply fall past this block,
+    * returning NULL, with `errno' appropriately set by `access'.
+    *
+    * When we _do_ get to here, then we can use `_fullpath' to
+    * resolve the full path for `name' into `resolved', but first,
+    * check that we have a suitable buffer, in which to return it.
+    */
 
-        /* By now, we should have a valid buffer.
-        * If we don't, then we know that `malloc' failed,
-        * so we can set `errno = ENOMEM' appropriately.
+    if ((retname = resolved) == NULL)
+    {
+        /* Caller didn't give us a buffer, so we'll exercise the
+        * option granted by SUSv3, and allocate one.
+        *
+        * `_fullpath' would do this for us, but it uses `malloc', and
+        * Microsoft's implementation doesn't set `errno' on failure.
+        * If we don't do this explicitly ourselves, then we will not
+        * know if `_fullpath' fails on `malloc' failure, or for some
+        * other reason, and we want to set `errno = ENOMEM' for the
+        * `malloc' failure case.
         */
 
+        retname = (char *)malloc(PATH_MAX);
         if (retname == NULL)
+        {
             errno = ENOMEM;
+            return NULL;
+        }
+    }
 
-        /* Otherwise, when we do have a valid buffer,
-        * `_fullpath' should only fail if the path name is too long.
-        */
+    /* Otherwise, when we do have a valid buffer,
+    * `_fullpath' should only fail if the path name is too long.
+    */
 
-        else if ((retname = _fullpath(retname, name, _MAX_PATH)) == NULL)
-            errno = ENAMETOOLONG;
+    wchar_t wideFullPathBuffer[PATH_MAX];
+    wchar_t *wideFullPath;
+    if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == NULL)
+    {
+        errno = ENAMETOOLONG;
+        return NULL;
     }
 
-    /* By the time we get to here,
-    * `retname' either points to the required resolved path name,
-    * or it is NULL, with `errno' set appropriately, either of which
-    * is our required return condition.
-    */
+    // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
+    // FIXME: Check for failure
+    size_t initialLength = wcslen(wideFullPath);
+    GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX);
+    GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1);
 
-    if (retname != NULL)
+    // Convert back to UTF-8
+    if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX))
     {
-        // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS
-        int initialLength = strlen(retname);
-        TCHAR buffer[MAX_PATH];
-        GetShortPathName(retname, buffer, MAX_PATH);
-        GetLongPathName(buffer, retname, initialLength + 1);
-
-        // Force drive to be upper case
-        if (retname[1] == ':')
-            retname[0] = toupper(retname[0]);
+        errno = EINVAL;
+        return NULL;
     }
 
+    // Force drive to be upper case
+    if (retname[1] == ':')
+        retname[0] = toupper(retname[0]);
+
     return retname;
 }
 
@@ -167,7 +201,27 @@ char* basename(char *path)
 // use _getcwd() instead of GetCurrentDirectory() because it updates errno
 char* getcwd(char* path, int max)
 {
-    return _getcwd(path, max);
+    assert(path == NULL || max <= PATH_MAX);
+    wchar_t wpath[PATH_MAX];
+    if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX))
+    {
+        // Caller is allowed to pass in NULL for `path`.
+        // In that case, we're supposed to allocate a
+        // buffer on the caller's behalf.
+        if (path == NULL)
+        {
+            max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1;
+            path = (char *)malloc(max);
+            if (path == NULL)
+            {
+                errno = ENOMEM;
+                return NULL;
+            }
+        }
+        if (wideToUtf8(wresult, path, max))
+            return path;
+    }
+    return NULL;
 }
 
 // use _chdir() instead of SetCurrentDirectory() because it updates errno

Modified: lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Live/DebuggerThread.cpp Tue Mar 22 12:58:09 2016
@@ -27,6 +27,7 @@
 #include "Plugins/Process/Windows/Common/ProcessWindowsLog.h"
 
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace lldb;
@@ -484,13 +485,15 @@ DebuggerThread::HandleLoadDllEvent(const
         return DBG_CONTINUE;
     }
 
-    std::vector<char> buffer(1);
-    DWORD required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
+    std::vector<wchar_t> buffer(1);
+    DWORD required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
     if (required_size > 0)
     {
         buffer.resize(required_size + 1);
-        required_size = GetFinalPathNameByHandle(info.hFile, &buffer[0], required_size + 1, VOLUME_NAME_DOS);
-        llvm::StringRef path_str(&buffer[0]);
+        required_size = GetFinalPathNameByHandleW(info.hFile, &buffer[0], required_size, VOLUME_NAME_DOS);
+        std::string path_str_utf8;
+        llvm::convertWideToUTF8(buffer.data(), path_str_utf8);
+        llvm::StringRef path_str = path_str_utf8;
         const char *path = path_str.data();
         if (path_str.startswith("\\\\?\\"))
             path += 4;

Modified: lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/Live/ProcessWindowsLive.cpp Tue Mar 22 12:58:09 2016
@@ -47,6 +47,7 @@
 #include "ProcessWindowsLive.h"
 #include "TargetThreadWindowsLive.h"
 
+#include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/raw_ostream.h"
 
@@ -61,17 +62,19 @@ namespace
 std::string
 GetProcessExecutableName(HANDLE process_handle)
 {
-    std::vector<char> file_name;
+    std::vector<wchar_t> file_name;
     DWORD file_name_size = MAX_PATH;  // first guess, not an absolute limit
     DWORD copied = 0;
     do
     {
         file_name_size *= 2;
         file_name.resize(file_name_size);
-        copied = ::GetModuleFileNameEx(process_handle, NULL, file_name.data(), file_name_size);
+        copied = ::GetModuleFileNameExW(process_handle, NULL, file_name.data(), file_name_size);
     } while (copied >= file_name_size);
     file_name.resize(copied);
-    return std::string(file_name.begin(), file_name.end());
+    std::string result;
+    llvm::convertWideToUTF8(file_name.data(), result);
+    return result;
 }
 
 std::string

Modified: lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Windows/MiniDump/ProcessWinMiniDump.cpp Tue Mar 22 12:58:09 2016
@@ -370,14 +370,21 @@ ProcessWinMiniDump::Impl::MapMiniDumpInt
 {
     Error error;
     const char *file = m_core_file.GetCString();
-    m_dump_file = ::CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    std::wstring wfile;
+    if (!llvm::ConvertUTF8toWide(file, wfile))
+    {
+        error.SetErrorString("Error converting path to UTF-16");
+        return error;
+    }
+    m_dump_file =
+        ::CreateFileW(wfile.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     if (m_dump_file == INVALID_HANDLE_VALUE)
     {
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
         return error;
     }
 
-    m_mapping = ::CreateFileMapping(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
+    m_mapping = ::CreateFileMappingW(m_dump_file, NULL, PAGE_READONLY, 0, 0, NULL);
     if (m_mapping == NULL)
     {
         error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
@@ -509,7 +516,7 @@ ProcessWinMiniDump::Impl::GetMiniDumpStr
     auto source_start = reinterpret_cast<const UTF16 *>(md_string->Buffer);
     const auto source_length = ::wcslen(md_string->Buffer);
     const auto source_end = source_start + source_length;
-    result.resize(4 * source_length); // worst case length
+    result.resize(UNI_MAX_UTF8_BYTES_PER_CODE_POINT * source_length); // worst case length
     auto result_start = reinterpret_cast<UTF8 *>(&result[0]);
     const auto result_end = result_start + result.size();
     ConvertUTF16toUTF8(&source_start, source_end, &result_start, result_end, strictConversion);

Modified: lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp (original)
+++ lldb/trunk/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp Tue Mar 22 12:58:09 2016
@@ -19,8 +19,11 @@
 
 #include "lldb/Core/Stream.h"
 #include "lldb/Host/File.h"
+#include "lldb/Host/FileSystem.h"
 #include "lldb/Interpreter/ScriptInterpreter.h"
 
+#include "llvm/Support/ConvertUTF.h"
+
 #include <stdio.h>
 
 #include "llvm/ADT/StringSwitch.h"
@@ -1162,9 +1165,7 @@ PythonFile::PythonFile(File &file, const
 
 PythonFile::PythonFile(const char *path, const char *mode)
 {
-    FILE *fp = nullptr;
-    fp = fopen(path, mode);
-    lldb_private::File file(fp, true);
+    lldb_private::File file(path, GetOptionsFromMode(mode));
     Reset(file, mode);
 }
 

Modified: lldb/trunk/source/Target/ProcessLaunchInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ProcessLaunchInfo.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/source/Target/ProcessLaunchInfo.cpp (original)
+++ lldb/trunk/source/Target/ProcessLaunchInfo.cpp Tue Mar 22 12:58:09 2016
@@ -13,14 +13,21 @@
 
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Host/Config.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/Log.h"
+#include "lldb/Host/Config.h"
 #include "lldb/Host/FileSystem.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
+#include "lldb/Host/HostInfo.h"
 #include "lldb/Target/FileAction.h"
+#include "lldb/Target/ProcessLaunchInfo.h"
 #include "lldb/Target/Target.h"
 
+#include "llvm/Support/ConvertUTF.h"
+
+#if !defined(_WIN32)
+#include <limits.h>
+#endif
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -449,8 +456,8 @@ ProcessLaunchInfo::ConvertArgumentsForLa
                         if (cwd && cwd[0])
                             new_path += cwd;
                     }
-                    const char *curr_path = getenv("PATH");
-                    if (curr_path)
+                    std::string curr_path;
+                    if (HostInfo::GetEnvironmentVar("PATH", curr_path))
                     {
                         if (new_path.size() > empty_path_len)
                             new_path += ':';

Modified: lldb/trunk/tools/driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/driver/Driver.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/tools/driver/Driver.cpp (original)
+++ lldb/trunk/tools/driver/Driver.cpp Tue Mar 22 12:58:09 2016
@@ -27,7 +27,6 @@
 
 #include <string>
 
-#include <thread>
 #include "lldb/API/SBBreakpoint.h"
 #include "lldb/API/SBCommandInterpreter.h"
 #include "lldb/API/SBCommandReturnObject.h"
@@ -37,11 +36,13 @@
 #include "lldb/API/SBHostOS.h"
 #include "lldb/API/SBLanguageRuntime.h"
 #include "lldb/API/SBListener.h"
+#include "lldb/API/SBProcess.h"
 #include "lldb/API/SBStream.h"
 #include "lldb/API/SBStringList.h"
 #include "lldb/API/SBTarget.h"
 #include "lldb/API/SBThread.h"
-#include "lldb/API/SBProcess.h"
+#include "llvm/Support/ConvertUTF.h"
+#include <thread>
 
 #if !defined(__APPLE__)
 #include "llvm/Support/DataTypes.h"
@@ -1298,7 +1299,11 @@ sigcont_handler (int signo)
 }
 
 int
-main (int argc, char const *argv[], const char *envp[])
+#ifdef WIN32
+wmain(int argc, wchar_t const *wargv[])
+#else
+main(int argc, char const *argv[])
+#endif
 {
 #ifdef _MSC_VER
 	// disable buffering on windows
@@ -1306,37 +1311,49 @@ main (int argc, char const *argv[], cons
 	setvbuf(stdin , NULL, _IONBF, 0);
 #endif
 
-    SBDebugger::Initialize();
-    
-    SBHostOS::ThreadCreated ("<lldb.driver.main-thread>");
-
-    signal(SIGINT, sigint_handler);
-#ifndef _MSC_VER
-    signal (SIGPIPE, SIG_IGN);
-    signal (SIGWINCH, sigwinch_handler);
-    signal (SIGTSTP, sigtstp_handler);
-    signal (SIGCONT, sigcont_handler);
+#ifdef _WIN32
+        // Convert wide arguments to UTF-8
+        std::vector<std::string> argvStrings(argc);
+        std::vector<const char *> argvPointers(argc);
+        for (int i = 0; i != argc; ++i)
+        {
+            llvm::convertWideToUTF8(wargv[i], argvStrings[i]);
+            argvPointers[i] = argvStrings[i].c_str();
+        }
+        const char **argv = argvPointers.data();
 #endif
 
-    // Create a scope for driver so that the driver object will destroy itself
-    // before SBDebugger::Terminate() is called.
-    {
-        Driver driver;
+        SBDebugger::Initialize();
 
-        bool exiting = false;
-        SBError error (driver.ParseArgs (argc, argv, stdout, exiting));
-        if (error.Fail())
-        {
-            const char *error_cstr = error.GetCString ();
-            if (error_cstr)
-                ::fprintf (stderr, "error: %s\n", error_cstr);
-        }
-        else if (!exiting)
+        SBHostOS::ThreadCreated("<lldb.driver.main-thread>");
+
+        signal(SIGINT, sigint_handler);
+#if !defined(_MSC_VER)
+        signal(SIGPIPE, SIG_IGN);
+        signal(SIGWINCH, sigwinch_handler);
+        signal(SIGTSTP, sigtstp_handler);
+        signal(SIGCONT, sigcont_handler);
+#endif
+
+        // Create a scope for driver so that the driver object will destroy itself
+        // before SBDebugger::Terminate() is called.
         {
-            driver.MainLoop ();
+            Driver driver;
+
+            bool exiting = false;
+            SBError error(driver.ParseArgs(argc, argv, stdout, exiting));
+            if (error.Fail())
+            {
+                const char *error_cstr = error.GetCString();
+                if (error_cstr)
+                    ::fprintf(stderr, "error: %s\n", error_cstr);
+            }
+            else if (!exiting)
+            {
+                driver.MainLoop();
+            }
         }
-    }
 
-    SBDebugger::Terminate();
-    return 0;
+        SBDebugger::Terminate();
+        return 0;
 }

Modified: lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnLLDBDebugSessionInfo.cpp Tue Mar 22 12:58:09 2016
@@ -18,15 +18,16 @@
 #include "lldb/API/SBBreakpointLocation.h"
 
 // In-house headers:
+#include "MICmdData.h"
 #include "MICmnLLDBDebugSessionInfo.h"
 #include "MICmnLLDBDebugger.h"
-#include "MICmnResources.h"
+#include "MICmnLLDBUtilSBValue.h"
 #include "MICmnMIResultRecord.h"
 #include "MICmnMIValueConst.h"
 #include "MICmnMIValueList.h"
 #include "MICmnMIValueTuple.h"
-#include "MICmdData.h"
-#include "MICmnLLDBUtilSBValue.h"
+#include "MICmnResources.h"
+#include "Platform.h"
 
 //++ ------------------------------------------------------------------------------------
 // Details: CMICmnLLDBDebugSessionInfo constructor.
@@ -614,7 +615,7 @@ CMICmnLLDBDebugSessionInfo::GetFrameInfo
 {
     lldb::SBFrame &rFrame = const_cast<lldb::SBFrame &>(vrFrame);
 
-    static char pBuffer[MAX_PATH];
+    static char pBuffer[PATH_MAX];
     const MIuint nBytes = rFrame.GetLineEntry().GetFileSpec().GetPath(&pBuffer[0], sizeof(pBuffer));
     MIunused(nBytes);
     CMIUtilString strResolvedPath(&pBuffer[0]);

Modified: lldb/trunk/tools/lldb-mi/MIUtilFileStd.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIUtilFileStd.cpp?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIUtilFileStd.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIUtilFileStd.cpp Tue Mar 22 12:58:09 2016
@@ -14,8 +14,11 @@
 #include <cerrno>
 
 // In-house headers:
-#include "MIUtilFileStd.h"
 #include "MICmnResources.h"
+#include "MIUtilFileStd.h"
+#include "lldb/Host/FileSystem.h"
+
+#include "llvm/Support/ConvertUTF.h"
 
 //++ ------------------------------------------------------------------------------------
 // Details: CMIUtilFileStd constructor.
@@ -82,7 +85,14 @@ CMIUtilFileStd::CreateWrite(const CMIUti
     m_pFileHandle = ::fopen(vFileNamePath.c_str(), "wb");
 #else
     // Open a file with exclusive write and shared read permissions
-    m_pFileHandle = ::_fsopen(vFileNamePath.c_str(), "wb", _SH_DENYWR);
+    std::wstring path;
+    if (llvm::ConvertUTF8toWide(vFileNamePath.c_str(), path))
+        m_pFileHandle = ::_wfsopen(path.c_str(), L"wb", _SH_DENYWR);
+    else
+    {
+        errno = EINVAL;
+        m_pFileHandle = nullptr;
+    }
 #endif // !defined( _MSC_VER )
 
     if (m_pFileHandle == nullptr)
@@ -221,8 +231,7 @@ CMIUtilFileStd::IsFileExist(const CMIUti
     if (vFileNamePath.empty())
         return false;
 
-    FILE *pTmp = nullptr;
-    pTmp = ::fopen(vFileNamePath.c_str(), "wb");
+    FILE *pTmp = lldb_private::FileSystem::Fopen(vFileNamePath.c_str(), "wb");
     if (pTmp != nullptr)
     {
         ::fclose(pTmp);

Modified: lldb/trunk/tools/lldb-mi/Platform.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/Platform.h?rev=264074&r1=264073&r2=264074&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/Platform.h (original)
+++ lldb/trunk/tools/lldb-mi/Platform.h Tue Mar 22 12:58:09 2016
@@ -58,7 +58,7 @@ struct termios
 typedef long pid_t;
 
 #define STDIN_FILENO 0
-#define PATH_MAX MAX_PATH
+#define PATH_MAX 32768
 #define snprintf _snprintf
 
 extern int ioctl(int d, int request, ...);




More information about the lldb-commits mailing list