summaryrefslogtreecommitdiff
path: root/source/Host/windows
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/windows')
-rw-r--r--source/Host/windows/ConnectionGenericFileWindows.cpp323
-rw-r--r--source/Host/windows/EditLineWin.cpp350
-rw-r--r--source/Host/windows/FileSystem.cpp107
-rw-r--r--source/Host/windows/Host.cpp275
-rw-r--r--source/Host/windows/HostInfoWindows.cpp120
-rw-r--r--source/Host/windows/HostProcessWindows.cpp120
-rw-r--r--source/Host/windows/HostThreadWindows.cpp75
-rw-r--r--source/Host/windows/LockFileWindows.cpp79
-rw-r--r--source/Host/windows/PipeWindows.cpp339
-rw-r--r--source/Host/windows/ProcessLauncherWindows.cpp159
-rw-r--r--source/Host/windows/ProcessRunLock.cpp82
-rw-r--r--source/Host/windows/Windows.cpp231
12 files changed, 0 insertions, 2260 deletions
diff --git a/source/Host/windows/ConnectionGenericFileWindows.cpp b/source/Host/windows/ConnectionGenericFileWindows.cpp
deleted file mode 100644
index e59e190dcb2d..000000000000
--- a/source/Host/windows/ConnectionGenericFileWindows.cpp
+++ /dev/null
@@ -1,323 +0,0 @@
-//===-- ConnectionGenericFileWindows.cpp ------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Timeout.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ConvertUTF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-// This is a simple helper class to package up the information needed to return
-// from a Read/Write operation function. Since there is a lot of code to be
-// run before exit regardless of whether the operation succeeded or failed,
-// combined with many possible return paths, this is the cleanest way to
-// represent it.
-class ReturnInfo {
-public:
- void Set(size_t bytes, ConnectionStatus status, DWORD error_code) {
- m_error.SetError(error_code, eErrorTypeWin32);
- m_bytes = bytes;
- m_status = status;
- }
-
- void Set(size_t bytes, ConnectionStatus status, llvm::StringRef error_msg) {
- m_error.SetErrorString(error_msg.data());
- m_bytes = bytes;
- m_status = status;
- }
-
- size_t GetBytes() const { return m_bytes; }
- ConnectionStatus GetStatus() const { return m_status; }
- const Status &GetError() const { return m_error; }
-
-private:
- Status m_error;
- size_t m_bytes;
- ConnectionStatus m_status;
-};
-}
-
-ConnectionGenericFile::ConnectionGenericFile()
- : m_file(INVALID_HANDLE_VALUE), m_owns_file(false) {
- ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- InitializeEventHandles();
-}
-
-ConnectionGenericFile::ConnectionGenericFile(lldb::file_t file, bool owns_file)
- : m_file(file), m_owns_file(owns_file) {
- ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- InitializeEventHandles();
-}
-
-ConnectionGenericFile::~ConnectionGenericFile() {
- if (m_owns_file && IsConnected())
- ::CloseHandle(m_file);
-
- ::CloseHandle(m_event_handles[kBytesAvailableEvent]);
- ::CloseHandle(m_event_handles[kInterruptEvent]);
-}
-
-void ConnectionGenericFile::InitializeEventHandles() {
- m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE, NULL);
-
- // Note, we should use a manual reset event for the hEvent argument of the
- // OVERLAPPED. This is because both WaitForMultipleObjects and
- // GetOverlappedResult (if you set the bWait argument to TRUE) will wait for
- // the event to be signalled. If we use an auto-reset event,
- // WaitForMultipleObjects will reset the event, return successfully, and then
- // GetOverlappedResult will block since the event is no longer signalled.
- m_event_handles[kBytesAvailableEvent] =
- ::CreateEvent(NULL, TRUE, FALSE, NULL);
-}
-
-bool ConnectionGenericFile::IsConnected() const {
- return m_file && (m_file != INVALID_HANDLE_VALUE);
-}
-
-lldb::ConnectionStatus ConnectionGenericFile::Connect(llvm::StringRef path,
- Status *error_ptr) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionGenericFile::Connect (url = '%s')",
- static_cast<void *>(this), path.str().c_str());
-
- if (!path.consume_front("file://")) {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'",
- path.str().c_str());
- return eConnectionStatusError;
- }
-
- if (IsConnected()) {
- ConnectionStatus status = Disconnect(error_ptr);
- if (status != eConnectionStatusSuccess)
- return status;
- }
-
- // 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.
- 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)
- error_ptr->SetError(::GetLastError(), eErrorTypeWin32);
- return eConnectionStatusError;
- }
-
- m_owns_file = true;
- m_uri.assign(path);
- return eConnectionStatusSuccess;
-}
-
-lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *error_ptr) {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log)
- log->Printf("%p ConnectionGenericFile::Disconnect ()",
- static_cast<void *>(this));
-
- if (!IsConnected())
- return eConnectionStatusSuccess;
-
- // Reset the handle so that after we unblock any pending reads, subsequent
- // calls to Read() will see a disconnected state.
- HANDLE old_file = m_file;
- m_file = INVALID_HANDLE_VALUE;
-
- // Set the disconnect event so that any blocking reads unblock, then cancel
- // any pending IO operations.
- ::CancelIoEx(old_file, &m_overlapped);
-
- // Close the file handle if we owned it, but don't close the event handles.
- // We could always reconnect with the same Connection instance.
- if (m_owns_file)
- ::CloseHandle(old_file);
-
- ::ZeroMemory(&m_file_position, sizeof(m_file_position));
- m_owns_file = false;
- m_uri.clear();
- return eConnectionStatusSuccess;
-}
-
-size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
- const Timeout<std::micro> &timeout,
- lldb::ConnectionStatus &status,
- Status *error_ptr) {
- ReturnInfo return_info;
- BOOL result = 0;
- DWORD bytes_read = 0;
-
- if (error_ptr)
- error_ptr->Clear();
-
- if (!IsConnected()) {
- return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
- goto finish;
- }
-
- m_overlapped.hEvent = m_event_handles[kBytesAvailableEvent];
-
- result = ::ReadFile(m_file, dst, dst_len, NULL, &m_overlapped);
- if (result || ::GetLastError() == ERROR_IO_PENDING) {
- if (!result) {
- // The expected return path. The operation is pending. Wait for the
- // operation to complete or be interrupted.
- DWORD milliseconds =
- timeout
- ? std::chrono::duration_cast<std::chrono::milliseconds>(*timeout)
- .count()
- : INFINITE;
- DWORD wait_result =
- ::WaitForMultipleObjects(llvm::array_lengthof(m_event_handles),
- m_event_handles, FALSE, milliseconds);
- // All of the events are manual reset events, so make sure we reset them
- // to non-signalled.
- switch (wait_result) {
- case WAIT_OBJECT_0 + kBytesAvailableEvent:
- break;
- case WAIT_OBJECT_0 + kInterruptEvent:
- return_info.Set(0, eConnectionStatusInterrupted, 0);
- goto finish;
- case WAIT_TIMEOUT:
- return_info.Set(0, eConnectionStatusTimedOut, 0);
- goto finish;
- case WAIT_FAILED:
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
- }
- // The data is ready. Figure out how much was read and return;
- if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read, FALSE)) {
- DWORD result_error = ::GetLastError();
- // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during
- // a blocking read. This triggers a call to CancelIoEx, which causes the
- // operation to complete and the result to be ERROR_OPERATION_ABORTED.
- if (result_error == ERROR_HANDLE_EOF ||
- result_error == ERROR_OPERATION_ABORTED ||
- result_error == ERROR_BROKEN_PIPE)
- return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
- else
- return_info.Set(bytes_read, eConnectionStatusError, result_error);
- } else if (bytes_read == 0)
- return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
- else
- return_info.Set(bytes_read, eConnectionStatusSuccess, 0);
-
- goto finish;
- } else if (::GetLastError() == ERROR_BROKEN_PIPE) {
- // The write end of a pipe was closed. This is equivalent to EOF.
- return_info.Set(0, eConnectionStatusEndOfFile, 0);
- } else {
- // An unknown error occurred. Fail out.
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- }
- goto finish;
-
-finish:
- status = return_info.GetStatus();
- if (error_ptr)
- *error_ptr = return_info.GetError();
-
- // kBytesAvailableEvent is a manual reset event. Make sure it gets reset
- // here so that any subsequent operations don't immediately see bytes
- // available.
- ResetEvent(m_event_handles[kBytesAvailableEvent]);
-
- IncrementFilePointer(return_info.GetBytes());
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log) {
- log->Printf("%p ConnectionGenericFile::Read() handle = %p, dst = %p, "
- "dst_len = %zu) => %zu, error = %s",
- this, m_file, dst, dst_len, return_info.GetBytes(),
- return_info.GetError().AsCString());
- }
-
- return return_info.GetBytes();
-}
-
-size_t ConnectionGenericFile::Write(const void *src, size_t src_len,
- lldb::ConnectionStatus &status,
- Status *error_ptr) {
- ReturnInfo return_info;
- DWORD bytes_written = 0;
- BOOL result = 0;
-
- if (error_ptr)
- error_ptr->Clear();
-
- if (!IsConnected()) {
- return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
- goto finish;
- }
-
- m_overlapped.hEvent = NULL;
-
- // Writes are not interruptible like reads are, so just block until it's
- // done.
- result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);
- if (!result && ::GetLastError() != ERROR_IO_PENDING) {
- return_info.Set(0, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
-
- if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_written, TRUE)) {
- return_info.Set(bytes_written, eConnectionStatusError, ::GetLastError());
- goto finish;
- }
-
- return_info.Set(bytes_written, eConnectionStatusSuccess, 0);
- goto finish;
-
-finish:
- status = return_info.GetStatus();
- if (error_ptr)
- *error_ptr = return_info.GetError();
-
- IncrementFilePointer(return_info.GetBytes());
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
- if (log) {
- log->Printf("%p ConnectionGenericFile::Write() handle = %p, src = %p, "
- "src_len = %zu) => %zu, error = %s",
- this, m_file, src, src_len, return_info.GetBytes(),
- return_info.GetError().AsCString());
- }
- return return_info.GetBytes();
-}
-
-std::string ConnectionGenericFile::GetURI() { return m_uri; }
-
-bool ConnectionGenericFile::InterruptRead() {
- return ::SetEvent(m_event_handles[kInterruptEvent]);
-}
-
-void ConnectionGenericFile::IncrementFilePointer(DWORD amount) {
- LARGE_INTEGER old_pos;
- old_pos.HighPart = m_overlapped.OffsetHigh;
- old_pos.LowPart = m_overlapped.Offset;
- old_pos.QuadPart += amount;
- m_overlapped.Offset = old_pos.LowPart;
- m_overlapped.OffsetHigh = old_pos.HighPart;
-}
diff --git a/source/Host/windows/EditLineWin.cpp b/source/Host/windows/EditLineWin.cpp
deleted file mode 100644
index 3bccc4e1a2c9..000000000000
--- a/source/Host/windows/EditLineWin.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-//===-- EditLineWin.cpp -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// this file is only relevant for Visual C++
-#if defined(_WIN32)
-
-#include "lldb/Host/windows/windows.h"
-
-#include "lldb/Host/windows/editlinewin.h"
-#include "llvm/Support/ErrorHandling.h"
-#include <assert.h>
-#include <vector>
-
-// edit line EL_ADDFN function pointer type
-typedef unsigned char (*el_addfn_func)(EditLine *e, int ch);
-typedef const char *(*el_prompt_func)(EditLine *);
-
-// edit line wrapper binding container
-struct el_binding {
- //
- const char *name;
- const char *help;
- // function pointer to callback routine
- el_addfn_func func;
- // ascii key this function is bound to
- const char *key;
-};
-
-// stored key bindings
-static std::vector<el_binding *> _bindings;
-
-// TODO: this should in fact be related to the exact edit line context we create
-static void *clientData = NULL;
-
-// store the current prompt string
-// default to what we expect to receive anyway
-static const char *_prompt = "(lldb) ";
-
-#if !defined(_WIP_INPUT_METHOD)
-
-static char *el_get_s(char *buffer, int chars) { return gets_s(buffer, chars); }
-#else
-
-static void con_output(char _in) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get the cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // output this char
- WriteConsoleOutputCharacterA(hout, &_in, 1, info.dwCursorPosition, &written);
- // advance cursor position
- info.dwCursorPosition.X++;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
-}
-
-static void con_backspace(void) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // nudge cursor backwards
- info.dwCursorPosition.X--;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
- // blank out the last character
- WriteConsoleOutputCharacterA(hout, " ", 1, info.dwCursorPosition, &written);
-}
-
-static void con_return(void) {
- HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
- DWORD written = 0;
- // get cursor position
- CONSOLE_SCREEN_BUFFER_INFO info;
- GetConsoleScreenBufferInfo(hout, &info);
- // move onto the new line
- info.dwCursorPosition.X = 0;
- info.dwCursorPosition.Y++;
- SetConsoleCursorPosition(hout, info.dwCursorPosition);
-}
-
-static bool runBind(char _key) {
- for (int i = 0; i < _bindings.size(); i++) {
- el_binding *bind = _bindings[i];
- if (bind->key[0] == _key) {
- bind->func((EditLine *)-1, _key);
- return true;
- }
- }
- return false;
-}
-
-// replacement get_s which is EL_BIND aware
-static char *el_get_s(char *buffer, int chars) {
- //
- char *head = buffer;
- //
- for (;; Sleep(10)) {
- //
- INPUT_RECORD _record;
- //
- DWORD _read = 0;
- if (ReadConsoleInputA(GetStdHandle(STD_INPUT_HANDLE), &_record, 1,
- &_read) == FALSE)
- break;
- // if we didn't read a key
- if (_read == 0)
- continue;
- // only interested in key events
- if (_record.EventType != KEY_EVENT)
- continue;
- // is the key down
- if (!_record.Event.KeyEvent.bKeyDown)
- continue;
- // read the ascii key character
- char _key = _record.Event.KeyEvent.uChar.AsciiChar;
- // non ascii conformant key press
- if (_key == 0) {
- // check the scan code
- // if VK_UP scroll back through history
- // if VK_DOWN scroll forward through history
- continue;
- }
- // try to execute any bind this key may have
- if (runBind(_key))
- continue;
- // if we read a return key
- if (_key == '\n' || _key == '\r') {
- con_return();
- break;
- }
- // key is backspace
- if (_key == 0x8) {
- // avoid deleting past beginning
- if (head > buffer) {
- con_backspace();
- head--;
- }
- continue;
- }
-
- // add this key to the input buffer
- if ((head - buffer) < (chars - 1)) {
- con_output(_key);
- *(head++) = _key;
- }
- }
- // insert end of line character
- *head = '\0';
-
- return buffer;
-}
-#endif
-
-// edit line initialize
-EditLine *el_init(const char *, FILE *, FILE *, FILE *) {
- //
- SetConsoleTitleA("lldb");
- // return dummy handle
- return (EditLine *)-1;
-}
-
-const char *el_gets(EditLine *el, int *length) {
- // print the prompt if we have one
- if (_prompt != NULL)
- printf("%s", _prompt);
- // create a buffer for the user input
- char *buffer = new char[MAX_PATH];
- // try to get user input string
- if (el_get_s(buffer, MAX_PATH)) {
- // get the string length in 'length'
- while (buffer[*length] != '\0')
- (*length)++;
- // return the input buffer
- // remember that this memory has the be free'd somewhere
- return buffer;
- } else {
- // on error
- delete[] buffer;
- return NULL;
- }
-}
-
-int el_set(EditLine *el, int code, ...) {
- va_list vl;
- va_start(vl, code);
- //
- switch (code) {
- // edit line set prompt message
- case (EL_PROMPT): {
- // EL_PROMPT, char *(*f)( EditLine *)
- // define a prompt printing function as 'f', which is to return a
- // string that
- // contains the prompt.
-
- // get the function pointer from the arg list
- void *func_vp = (void *)va_arg(vl, el_prompt_func);
- // cast to suitable prototype
- el_prompt_func func_fp = (el_prompt_func)func_vp;
- // call to get the prompt as a string
- _prompt = func_fp(el);
- } break;
-
- case (EL_PROMPT_ESC): {
- // EL_PROMPT, char *(*f)( EditLine *)
- // define a prompt printing function as 'f', which is to return a
- // string that
- // contains the prompt.
-
- // get the function pointer from the arg list
- void *func_vp = (void *)va_arg(vl, el_prompt_func);
- va_arg(vl, int);
- // call to get the prompt as a string
- el_prompt_func func_fp = (el_prompt_func)func_vp;
- _prompt = func_fp(el);
- } break;
-
- case (EL_EDITOR): {
- // EL_EDITOR, const char *mode
- // set editing mode to "emacs" or "vi"
- } break;
- case (EL_HIST): {
- // EL_HIST, History *(*fun)(History *, int op, ... ), const char *ptr
- // defines which history function to use, which is usually history().
- // Ptr should be the
- // value returned by history_init().
- } break;
- case (EL_ADDFN): {
- // EL_ADDFN, const char *name, const char *help, unsigned char
- // (*func)(EditLine *e, int ch)
- // add a user defined function, func), referred to as 'name' which is
- // invoked when a key which is bound to 'name' is
- // entered. 'help' is a description of 'name'. at invocation time, 'ch'
- // is the key which caused the invocation. the
- // return value of 'func()' should be one of:
- // CC_NORM add a normal character
- // CC_NEWLINE end of line was entered
- // CC_EOF EOF was entered
- // CC_ARGHACK expecting further command input as arguments, do
- // nothing visually.
- // CC_REFRESH refresh display.
- // CC_REFRESH_BEEP refresh display and beep.
- // CC_CURSOR cursor moved so update and perform CC_REFRESH
- // CC_REDISPLAY redisplay entire input line. this is useful
- // if a key binding outputs extra information.
- // CC_ERROR an error occurred. beep and flush tty.
- // CC_FATAL fatal error, reset tty to known state.
-
- el_binding *binding = new el_binding;
- binding->name = va_arg(vl, const char *);
- binding->help = va_arg(vl, const char *);
- binding->func = va_arg(vl, el_addfn_func);
- binding->key = 0;
- // add this to the bindings list
- _bindings.push_back(binding);
- } break;
- case (EL_BIND): {
- // EL_BIND, const char *, ..., NULL
- // perform the BIND built-in command. Refer to editrc(5) for more
- // information.
-
- const char *name = va_arg(vl, const char *);
-
- for (auto bind : _bindings) {
- if (strcmp(bind->name, name) == 0) {
- bind->key = va_arg(vl, const char *);
- break;
- }
- }
-
- } break;
- case (EL_CLIENTDATA): {
- clientData = va_arg(vl, void *);
- } break;
- }
- return 0;
-}
-
-void el_end(EditLine *el) {
- // assert( !"Not implemented!" );
-}
-
-void el_reset(EditLine *) { llvm_unreachable("Not implemented!"); }
-
-int el_getc(EditLine *, char *) {
- llvm_unreachable("Not implemented!");
-}
-
-void el_push(EditLine *, const char *) {}
-
-void el_beep(EditLine *) { Beep(1000, 500); }
-
-int el_parse(EditLine *, int, const char **) {
- llvm_unreachable("Not implemented!");
-}
-
-int el_get(EditLine *el, int code, ...) {
- va_list vl;
- va_start(vl, code);
-
- switch (code) {
- case (EL_CLIENTDATA): {
- void **dout = va_arg(vl, void **);
- *dout = clientData;
- } break;
- default:
- llvm_unreachable("Not implemented!");
- }
- return 0;
-}
-
-int el_source(EditLine *el, const char *file) {
- // init edit line by reading the contents of 'file' nothing to do here on
- // windows...
- return 0;
-}
-
-void el_resize(EditLine *) { llvm_unreachable("Not implemented!"); }
-
-const LineInfo *el_line(EditLine *el) { return 0; }
-
-int el_insertstr(EditLine *, const char *) {
- // assert( !"Not implemented!" );
- return 0;
-}
-
-void el_deletestr(EditLine *, int) { llvm_unreachable("Not implemented!"); }
-
-History *history_init(void) {
- // return dummy handle
- return (History *)-1;
-}
-
-void history_end(History *) {
- // assert( !"Not implemented!" );
-}
-
-int history(History *, HistEvent *, int op, ...) {
- // perform operation 'op' on the history list with optional arguments as
- // needed by the operation.
- return 0;
-}
-
-#endif
diff --git a/source/Host/windows/FileSystem.cpp b/source/Host/windows/FileSystem.cpp
deleted file mode 100644
index 3217cdc8480a..000000000000
--- a/source/Host/windows/FileSystem.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-//===-- FileSystem.cpp ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/windows.h"
-
-#include <shellapi.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/windows/AutoHandle.h"
-#include "lldb/Host/windows/PosixApi.h"
-
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/FileSystem.h"
-
-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";
-
-Status FileSystem::Symlink(const FileSpec &src, const FileSpec &dst) {
- Status error;
- 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);
- return error;
- }
- bool is_directory = !!(attrib & FILE_ATTRIBUTE_DIRECTORY);
- DWORD flag = is_directory ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
- BOOL result = ::CreateSymbolicLinkW(wsrc.c_str(), wdst.c_str(), flag);
- if (!result)
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
- return error;
-}
-
-Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) {
- Status error;
- 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;
- }
-
- 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 = ::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(path, FileSpec::Style::native);
-
- ::CloseHandle(h);
- return error;
-}
-
-Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) {
- return Status("ResolveSymbolicLink() isn't implemented on Windows");
-}
-
-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::Open(const char *path, int flags, int mode) {
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath))
- return -1;
- int result;
- ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
- return result;
-}
diff --git a/source/Host/windows/Host.cpp b/source/Host/windows/Host.cpp
deleted file mode 100644
index 3ac16a42286a..000000000000
--- a/source/Host/windows/Host.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-//===-- source/Host/windows/Host.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/AutoHandle.h"
-#include "lldb/Host/windows/windows.h"
-#include <stdio.h>
-
-#include "lldb/Host/FileSystem.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Host/HostInfo.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Utility/DataBufferHeap.h"
-#include "lldb/Utility/DataExtractor.h"
-#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Status.h"
-#include "lldb/Utility/StructuredData.h"
-
-#include "llvm/Support/ConvertUTF.h"
-
-// Windows includes
-#include <tlhelp32.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-bool GetTripleForProcess(const FileSpec &executable, llvm::Triple &triple) {
- // Open the PE File as a binary file, and parse just enough information to
- // determine the machine type.
- File imageBinary;
- FileSystem::Instance().Open(imageBinary, executable, File::eOpenOptionRead,
- lldb::eFilePermissionsUserRead);
- imageBinary.SeekFromStart(0x3c);
- int32_t peOffset = 0;
- uint32_t peHead = 0;
- uint16_t machineType = 0;
- size_t readSize = sizeof(peOffset);
- imageBinary.Read(&peOffset, readSize);
- imageBinary.SeekFromStart(peOffset);
- imageBinary.Read(&peHead, readSize);
- if (peHead != 0x00004550) // "PE\0\0", little-endian
- return false; // Status: Can't find PE header
- readSize = 2;
- imageBinary.Read(&machineType, readSize);
- triple.setVendor(llvm::Triple::PC);
- triple.setOS(llvm::Triple::Win32);
- triple.setArch(llvm::Triple::UnknownArch);
- if (machineType == 0x8664)
- triple.setArch(llvm::Triple::x86_64);
- else if (machineType == 0x14c)
- triple.setArch(llvm::Triple::x86);
-
- return true;
-}
-
-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<wchar_t> buffer(PATH_MAX);
- DWORD dwSize = buffer.size();
- if (!::QueryFullProcessImageNameW(handle.get(), 0, &buffer[0], &dwSize))
- return false;
- return llvm::convertWideToUTF8(buffer.data(), path);
-}
-
-void GetProcessExecutableAndTriple(const AutoHandle &handle,
- ProcessInstanceInfo &process) {
- // We may not have permissions to read the path from the process. So start
- // off by setting the executable file to whatever Toolhelp32 gives us, and
- // then try to enhance this with more detailed information, but fail
- // gracefully.
- std::string executable;
- llvm::Triple triple;
- triple.setVendor(llvm::Triple::PC);
- triple.setOS(llvm::Triple::Win32);
- triple.setArch(llvm::Triple::UnknownArch);
- if (GetExecutableForProcess(handle, executable)) {
- FileSpec executableFile(executable.c_str());
- process.SetExecutableFile(executableFile, true);
- GetTripleForProcess(executableFile, triple);
- }
- process.SetArchitecture(ArchSpec(triple));
-
- // TODO(zturner): Add the ability to get the process user name.
-}
-}
-
-lldb::thread_t Host::GetCurrentThread() {
- return lldb::thread_t(::GetCurrentThread());
-}
-
-void Host::Kill(lldb::pid_t pid, int signo) {
- TerminateProcess((HANDLE)pid, 1);
-}
-
-const char *Host::GetSignalAsCString(int signo) { return NULL; }
-
-FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) {
- FileSpec module_filespec;
-
- HMODULE hmodule = NULL;
- if (!::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- (LPCTSTR)host_addr, &hmodule))
- return module_filespec;
-
- std::vector<wchar_t> buffer(PATH_MAX);
- DWORD chars_copied = 0;
- do {
- 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());
- std::string path;
- if (!llvm::convertWideToUTF8(buffer.data(), path))
- return module_filespec;
- module_filespec.SetFile(path, FileSpec::Style::native);
- return module_filespec;
-}
-
-uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
- ProcessInstanceInfoList &process_infos) {
- process_infos.Clear();
-
- AutoHandle snapshot(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0));
- if (!snapshot.IsValid())
- return 0;
-
- PROCESSENTRY32W pe = {};
- pe.dwSize = sizeof(PROCESSENTRY32W);
- if (Process32FirstW(snapshot.get(), &pe)) {
- do {
- AutoHandle handle(::OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE,
- pe.th32ProcessID),
- nullptr);
-
- ProcessInstanceInfo process;
- std::string exeFile;
- llvm::convertWideToUTF8(pe.szExeFile, exeFile);
- process.SetExecutableFile(FileSpec(exeFile), 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 (Process32NextW(snapshot.get(), &pe));
- }
- return process_infos.GetSize();
-}
-
-bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
- process_info.Clear();
-
- AutoHandle handle(
- ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid),
- nullptr);
- if (!handle.IsValid())
- return false;
-
- process_info.SetProcessID(pid);
- GetProcessExecutableAndTriple(handle, process_info);
-
- // Need to read the PEB to get parent process and command line arguments.
- return true;
-}
-
-HostThread Host::StartMonitoringChildProcess(
- const Host::MonitorChildProcessCallback &callback, lldb::pid_t pid,
- bool monitor_signals) {
- return HostThread();
-}
-
-Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
- Status error;
- if (launch_info.GetFlags().Test(eLaunchFlagShellExpandArguments)) {
- FileSpec expand_tool_spec = HostInfo::GetSupportExeDir();
- if (!expand_tool_spec) {
- error.SetErrorString("could not find support executable directory for "
- "the lldb-argdumper tool");
- return error;
- }
- expand_tool_spec.AppendPathComponent("lldb-argdumper.exe");
- if (!FileSystem::Instance().Exists(expand_tool_spec)) {
- error.SetErrorString("could not find the lldb-argdumper tool");
- return error;
- }
-
- std::string quoted_cmd_string;
- launch_info.GetArguments().GetQuotedCommandString(quoted_cmd_string);
- std::replace(quoted_cmd_string.begin(), quoted_cmd_string.end(), '\\', '/');
- StreamString expand_command;
-
- expand_command.Printf("\"%s\" %s", expand_tool_spec.GetPath().c_str(),
- quoted_cmd_string.c_str());
-
- int status;
- std::string output;
- std::string command = expand_command.GetString();
- RunShellCommand(command.c_str(), launch_info.GetWorkingDirectory(), &status,
- nullptr, &output, std::chrono::seconds(10));
-
- if (status != 0) {
- error.SetErrorStringWithFormat("lldb-argdumper exited with error %d",
- status);
- return error;
- }
-
- auto data_sp = StructuredData::ParseJSON(output);
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto dict_sp = data_sp->GetAsDictionary();
- if (!data_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_sp = dict_sp->GetObjectForDotSeparatedPath("arguments");
- if (!args_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- auto args_array_sp = args_sp->GetAsArray();
- if (!args_array_sp) {
- error.SetErrorString("invalid JSON");
- return error;
- }
-
- launch_info.GetArguments().Clear();
-
- for (size_t i = 0; i < args_array_sp->GetSize(); i++) {
- auto item_sp = args_array_sp->GetItemAtIndex(i);
- if (!item_sp)
- continue;
- auto str_sp = item_sp->GetAsString();
- if (!str_sp)
- continue;
-
- launch_info.GetArguments().AppendArgument(str_sp->GetValue());
- }
- }
-
- return error;
-}
-
-Environment Host::GetEnvironment() {
- Environment 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.
- LPWCH environment_block = ::GetEnvironmentStringsW();
- while (*environment_block != L'\0') {
- 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.insert(current_var);
-
- environment_block += current_var_size;
- }
- return env;
-}
diff --git a/source/Host/windows/HostInfoWindows.cpp b/source/Host/windows/HostInfoWindows.cpp
deleted file mode 100644
index 81392d9a85b3..000000000000
--- a/source/Host/windows/HostInfoWindows.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- HostInfoWindows.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/windows.h"
-
-#include <objbase.h>
-
-#include <mutex>
-
-#include "lldb/Host/windows/HostInfoWindows.h"
-#include "lldb/Host/windows/PosixApi.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/ConvertUTF.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/Threading.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb_private;
-
-FileSpec HostInfoWindows::m_program_filespec;
-
-void HostInfoWindows::Initialize() {
- ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
- HostInfoBase::Initialize();
-}
-
-void HostInfoWindows::Terminate() {
- HostInfoBase::Terminate();
- ::CoUninitialize();
-}
-
-size_t HostInfoWindows::GetPageSize() {
- SYSTEM_INFO systemInfo;
- GetNativeSystemInfo(&systemInfo);
- return systemInfo.dwPageSize;
-}
-
-llvm::VersionTuple HostInfoWindows::GetOSVersion() {
- OSVERSIONINFOEX info;
-
- ZeroMemory(&info, sizeof(OSVERSIONINFOEX));
- info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
-#pragma warning(push)
-#pragma warning(disable : 4996)
- // Starting with Microsoft SDK for Windows 8.1, this function is deprecated
- // in favor of the new Windows Version Helper APIs. Since we don't specify a
- // minimum SDK version, it's easier to simply disable the warning rather than
- // try to support both APIs.
- if (GetVersionEx((LPOSVERSIONINFO)&info) == 0)
- return llvm::VersionTuple();
-#pragma warning(pop)
-
- return llvm::VersionTuple(info.dwMajorVersion, info.dwMinorVersion,
- info.wServicePackMajor);
-}
-
-bool HostInfoWindows::GetOSBuildString(std::string &s) {
- s.clear();
- llvm::VersionTuple version = GetOSVersion();
- if (version.empty())
- return false;
-
- llvm::raw_string_ostream stream(s);
- stream << "Windows NT " << version.getAsString();
- return true;
-}
-
-bool HostInfoWindows::GetOSKernelDescription(std::string &s) {
- return GetOSBuildString(s);
-}
-
-bool HostInfoWindows::GetHostname(std::string &s) {
- wchar_t buffer[MAX_COMPUTERNAME_LENGTH + 1];
- DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
- if (!::GetComputerNameW(buffer, &dwSize))
- return false;
-
- return llvm::convertWideToUTF8(buffer, s);
-}
-
-FileSpec HostInfoWindows::GetProgramFileSpec() {
- static llvm::once_flag g_once_flag;
- llvm::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, FileSpec::Style::native);
- });
- return m_program_filespec;
-}
-
-FileSpec HostInfoWindows::GetDefaultShell() {
- // Try to retrieve ComSpec from the environment. On the rare occasion
- // that it fails, try a well-known path for ComSpec instead.
-
- std::string shell;
- if (GetEnvironmentVar("ComSpec", shell))
- return FileSpec(shell);
-
- return FileSpec("C:\\Windows\\system32\\cmd.exe");
-}
-
-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;
-}
diff --git a/source/Host/windows/HostProcessWindows.cpp b/source/Host/windows/HostProcessWindows.cpp
deleted file mode 100644
index 701167ff6fea..000000000000
--- a/source/Host/windows/HostProcessWindows.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-//===-- HostProcessWindows.cpp ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/HostProcessWindows.h"
-#include "lldb/Host/HostThread.h"
-#include "lldb/Host/ThreadLauncher.h"
-#include "lldb/Host/windows/windows.h"
-#include "lldb/Utility/FileSpec.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/ConvertUTF.h"
-
-#include <psapi.h>
-
-using namespace lldb_private;
-
-namespace {
-struct MonitorInfo {
- Host::MonitorChildProcessCallback callback;
- HANDLE process_handle;
-};
-}
-
-HostProcessWindows::HostProcessWindows()
- : HostNativeProcessBase(), m_owns_handle(true) {}
-
-HostProcessWindows::HostProcessWindows(lldb::process_t process)
- : HostNativeProcessBase(process), m_owns_handle(true) {}
-
-HostProcessWindows::~HostProcessWindows() { Close(); }
-
-void HostProcessWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
-
-Status HostProcessWindows::Terminate() {
- Status error;
- if (m_process == nullptr)
- error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
-
- if (!::TerminateProcess(m_process, 0))
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
-
- return error;
-}
-
-Status HostProcessWindows::GetMainModule(FileSpec &file_spec) const {
- Status error;
- if (m_process == nullptr)
- error.SetError(ERROR_INVALID_HANDLE, lldb::eErrorTypeWin32);
-
- 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, FileSpec::Style::native);
- else
- error.SetErrorString("Error converting path to UTF-8");
- } else
- error.SetError(::GetLastError(), lldb::eErrorTypeWin32);
-
- return error;
-}
-
-lldb::pid_t HostProcessWindows::GetProcessId() const {
- return (m_process == LLDB_INVALID_PROCESS) ? -1 : ::GetProcessId(m_process);
-}
-
-bool HostProcessWindows::IsRunning() const {
- if (m_process == nullptr)
- return false;
-
- DWORD code = 0;
- if (!::GetExitCodeProcess(m_process, &code))
- return false;
-
- return (code == STILL_ACTIVE);
-}
-
-HostThread HostProcessWindows::StartMonitoring(
- const Host::MonitorChildProcessCallback &callback, bool monitor_signals) {
- HostThread monitor_thread;
- MonitorInfo *info = new MonitorInfo;
- info->callback = callback;
-
- // Since the life of this HostProcessWindows instance and the life of the
- // process may be different, duplicate the handle so that the monitor thread
- // can have ownership over its own copy of the handle.
- HostThread result;
- if (::DuplicateHandle(GetCurrentProcess(), m_process, GetCurrentProcess(),
- &info->process_handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
- result = ThreadLauncher::LaunchThread("ChildProcessMonitor",
- HostProcessWindows::MonitorThread,
- info, nullptr);
- return result;
-}
-
-lldb::thread_result_t HostProcessWindows::MonitorThread(void *thread_arg) {
- DWORD exit_code;
-
- MonitorInfo *info = static_cast<MonitorInfo *>(thread_arg);
- if (info) {
- ::WaitForSingleObject(info->process_handle, INFINITE);
- ::GetExitCodeProcess(info->process_handle, &exit_code);
- info->callback(::GetProcessId(info->process_handle), true, 0, exit_code);
- ::CloseHandle(info->process_handle);
- delete (info);
- }
- return 0;
-}
-
-void HostProcessWindows::Close() {
- if (m_owns_handle && m_process != LLDB_INVALID_PROCESS)
- ::CloseHandle(m_process);
- m_process = nullptr;
-}
diff --git a/source/Host/windows/HostThreadWindows.cpp b/source/Host/windows/HostThreadWindows.cpp
deleted file mode 100644
index b516230e7fa4..000000000000
--- a/source/Host/windows/HostThreadWindows.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-//===-- HostThreadWindows.cpp -----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/Status.h"
-
-#include "lldb/Host/windows/HostThreadWindows.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-void __stdcall ExitThreadProxy(ULONG_PTR dwExitCode) {
- ::ExitThread(dwExitCode);
-}
-}
-
-HostThreadWindows::HostThreadWindows()
- : HostNativeThreadBase(), m_owns_handle(true) {}
-
-HostThreadWindows::HostThreadWindows(lldb::thread_t thread)
- : HostNativeThreadBase(thread), m_owns_handle(true) {}
-
-HostThreadWindows::~HostThreadWindows() { Reset(); }
-
-void HostThreadWindows::SetOwnsHandle(bool owns) { m_owns_handle = owns; }
-
-Status HostThreadWindows::Join(lldb::thread_result_t *result) {
- Status error;
- if (IsJoinable()) {
- DWORD wait_result = ::WaitForSingleObject(m_thread, INFINITE);
- if (WAIT_OBJECT_0 == wait_result && result) {
- DWORD exit_code = 0;
- if (!::GetExitCodeThread(m_thread, &exit_code))
- *result = 0;
- *result = exit_code;
- } else if (WAIT_OBJECT_0 != wait_result)
- error.SetError(::GetLastError(), eErrorTypeWin32);
- } else
- error.SetError(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- Reset();
- return error;
-}
-
-Status HostThreadWindows::Cancel() {
- Status error;
-
- DWORD result = ::QueueUserAPC(::ExitThreadProxy, m_thread, 0);
- error.SetError(result, eErrorTypeWin32);
- return error;
-}
-
-lldb::tid_t HostThreadWindows::GetThreadId() const {
- return ::GetThreadId(m_thread);
-}
-
-void HostThreadWindows::Reset() {
- if (m_owns_handle && m_thread != LLDB_INVALID_HOST_THREAD)
- ::CloseHandle(m_thread);
-
- HostNativeThreadBase::Reset();
-}
-
-bool HostThreadWindows::EqualsThread(lldb::thread_t thread) const {
- return GetThreadId() == ::GetThreadId(thread);
-}
diff --git a/source/Host/windows/LockFileWindows.cpp b/source/Host/windows/LockFileWindows.cpp
deleted file mode 100644
index 2178fd1f5f6c..000000000000
--- a/source/Host/windows/LockFileWindows.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- LockFileWindows.cpp -------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/LockFileWindows.h"
-
-#include <io.h>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-
-Status fileLock(HANDLE file_handle, DWORD flags, const uint64_t start,
- const uint64_t len) {
- if (start != 0)
- return Status("Non-zero start lock regions are not supported");
-
- OVERLAPPED overlapped = {};
-
- if (!::LockFileEx(file_handle, flags, 0, len, 0, &overlapped) &&
- ::GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD bytes;
- if (!::GetOverlappedResult(file_handle, &overlapped, &bytes, TRUE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- return Status();
-}
-
-} // namespace
-
-LockFileWindows::LockFileWindows(int fd)
- : LockFileBase(fd), m_file(reinterpret_cast<HANDLE>(_get_osfhandle(fd))) {}
-
-LockFileWindows::~LockFileWindows() { Unlock(); }
-
-bool LockFileWindows::IsValidFile() const {
- return LockFileBase::IsValidFile() && m_file != INVALID_HANDLE_VALUE;
-}
-
-Status LockFileWindows::DoWriteLock(const uint64_t start, const uint64_t len) {
- return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK, start, len);
-}
-
-Status LockFileWindows::DoTryWriteLock(const uint64_t start,
- const uint64_t len) {
- return fileLock(m_file, LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY,
- start, len);
-}
-
-Status LockFileWindows::DoReadLock(const uint64_t start, const uint64_t len) {
- return fileLock(m_file, 0, start, len);
-}
-
-Status LockFileWindows::DoTryReadLock(const uint64_t start,
- const uint64_t len) {
- return fileLock(m_file, LOCKFILE_FAIL_IMMEDIATELY, start, len);
-}
-
-Status LockFileWindows::DoUnlock() {
- OVERLAPPED overlapped = {};
-
- if (!::UnlockFileEx(m_file, 0, m_len, 0, &overlapped) &&
- ::GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD bytes;
- if (!::GetOverlappedResult(m_file, &overlapped, &bytes, TRUE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- return Status();
-}
diff --git a/source/Host/windows/PipeWindows.cpp b/source/Host/windows/PipeWindows.cpp
deleted file mode 100644
index 57221a72899c..000000000000
--- a/source/Host/windows/PipeWindows.cpp
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- PipeWindows.cpp -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/PipeWindows.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/Process.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <fcntl.h>
-#include <io.h>
-#include <rpc.h>
-
-#include <atomic>
-#include <string>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-std::atomic<uint32_t> g_pipe_serial(0);
-constexpr llvm::StringLiteral g_pipe_name_prefix = "\\\\.\\Pipe\\";
-} // namespace
-
-PipeWindows::PipeWindows()
- : m_read(INVALID_HANDLE_VALUE), m_write(INVALID_HANDLE_VALUE),
- m_read_fd(PipeWindows::kInvalidDescriptor),
- m_write_fd(PipeWindows::kInvalidDescriptor) {
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-PipeWindows::PipeWindows(pipe_t read, pipe_t write)
- : m_read((HANDLE)read), m_write((HANDLE)write),
- m_read_fd(PipeWindows::kInvalidDescriptor),
- m_write_fd(PipeWindows::kInvalidDescriptor) {
- assert(read != LLDB_INVALID_PIPE || write != LLDB_INVALID_PIPE);
-
- // Don't risk in passing file descriptors and getting handles from them by
- // _get_osfhandle since the retrieved handles are highly likely unrecognized
- // in the current process and usually crashes the program. Pass handles
- // instead since the handle can be inherited.
-
- if (read != LLDB_INVALID_PIPE) {
- m_read_fd = _open_osfhandle((intptr_t)read, _O_RDONLY);
- // Make sure the fd and native handle are consistent.
- if (m_read_fd < 0)
- m_read = INVALID_HANDLE_VALUE;
- }
-
- if (write != LLDB_INVALID_PIPE) {
- m_write_fd = _open_osfhandle((intptr_t)write, _O_WRONLY);
- if (m_write_fd < 0)
- m_write = INVALID_HANDLE_VALUE;
- }
-
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-PipeWindows::~PipeWindows() { Close(); }
-
-Status PipeWindows::CreateNew(bool child_process_inherit) {
- // Create an anonymous pipe with the specified inheritance.
- SECURITY_ATTRIBUTES sa{sizeof(SECURITY_ATTRIBUTES), 0,
- child_process_inherit ? TRUE : FALSE};
- BOOL result = ::CreatePipe(&m_read, &m_write, &sa, 1024);
- if (result == FALSE)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEventA(nullptr, TRUE, FALSE, nullptr);
-
- m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-
- return Status();
-}
-
-Status PipeWindows::CreateNewNamed(bool child_process_inherit) {
- // Even for anonymous pipes, we open a named pipe. This is because you
- // cannot get overlapped i/o on Windows without using a named pipe. So we
- // synthesize a unique name.
- uint32_t serial = g_pipe_serial.fetch_add(1);
- std::string pipe_name;
- llvm::raw_string_ostream pipe_name_stream(pipe_name);
- pipe_name_stream << "lldb.pipe." << ::GetCurrentProcessId() << "." << serial;
- pipe_name_stream.flush();
-
- return CreateNew(pipe_name.c_str(), child_process_inherit);
-}
-
-Status PipeWindows::CreateNew(llvm::StringRef name,
- bool child_process_inherit) {
- if (name.empty())
- return Status(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
-
- if (CanRead() || CanWrite())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- std::string pipe_path = g_pipe_name_prefix;
- pipe_path.append(name);
-
- // Always open for overlapped i/o. We implement blocking manually in Read
- // and Write.
- DWORD read_mode = FILE_FLAG_OVERLAPPED;
- 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 Status(::GetLastError(), eErrorTypeWin32);
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
-
- // Open the write end of the pipe. Note that closing either the read or
- // write end of the pipe could directly close the pipe itself.
- Status result = OpenNamedPipe(name, child_process_inherit, false);
- if (!result.Success()) {
- CloseReadFileDescriptor();
- return result;
- }
-
- return result;
-}
-
-Status PipeWindows::CreateWithUniqueName(llvm::StringRef prefix,
- bool child_process_inherit,
- llvm::SmallVectorImpl<char> &name) {
- llvm::SmallString<128> pipe_name;
- Status error;
- ::UUID unique_id;
- RPC_CSTR unique_string;
- RPC_STATUS status = ::UuidCreate(&unique_id);
- if (status == RPC_S_OK || status == RPC_S_UUID_LOCAL_ONLY)
- status = ::UuidToStringA(&unique_id, &unique_string);
- if (status == RPC_S_OK) {
- pipe_name = prefix;
- pipe_name += "-";
- pipe_name += reinterpret_cast<char *>(unique_string);
- ::RpcStringFreeA(&unique_string);
- error = CreateNew(pipe_name, child_process_inherit);
- } else {
- error.SetError(status, eErrorTypeWin32);
- }
- if (error.Success())
- name = pipe_name;
- return error;
-}
-
-Status PipeWindows::OpenAsReader(llvm::StringRef name,
- bool child_process_inherit) {
- if (CanRead())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- return OpenNamedPipe(name, child_process_inherit, true);
-}
-
-Status
-PipeWindows::OpenAsWriterWithTimeout(llvm::StringRef name,
- bool child_process_inherit,
- const std::chrono::microseconds &timeout) {
- if (CanWrite())
- return Status(ERROR_ALREADY_EXISTS, eErrorTypeWin32);
-
- return OpenNamedPipe(name, child_process_inherit, false);
-}
-
-Status PipeWindows::OpenNamedPipe(llvm::StringRef name,
- bool child_process_inherit, bool is_read) {
- if (name.empty())
- return Status(ERROR_INVALID_PARAMETER, eErrorTypeWin32);
-
- assert(is_read ? !CanRead() : !CanWrite());
-
- SECURITY_ATTRIBUTES attributes = {};
- attributes.bInheritHandle = child_process_inherit;
-
- std::string pipe_path = g_pipe_name_prefix;
- pipe_path.append(name);
-
- if (is_read) {
- m_read = ::CreateFileA(pipe_path.c_str(), GENERIC_READ, 0, &attributes,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE == m_read)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_read_fd = _open_osfhandle((intptr_t)m_read, _O_RDONLY);
-
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- m_read_overlapped.hEvent = ::CreateEvent(nullptr, TRUE, FALSE, nullptr);
- } else {
- m_write = ::CreateFileA(pipe_path.c_str(), GENERIC_WRITE, 0, &attributes,
- OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
- if (INVALID_HANDLE_VALUE == m_write)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- m_write_fd = _open_osfhandle((intptr_t)m_write, _O_WRONLY);
-
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
- }
-
- return Status();
-}
-
-int PipeWindows::GetReadFileDescriptor() const { return m_read_fd; }
-
-int PipeWindows::GetWriteFileDescriptor() const { return m_write_fd; }
-
-int PipeWindows::ReleaseReadFileDescriptor() {
- if (!CanRead())
- return PipeWindows::kInvalidDescriptor;
- int result = m_read_fd;
- m_read_fd = PipeWindows::kInvalidDescriptor;
- if (m_read_overlapped.hEvent)
- ::CloseHandle(m_read_overlapped.hEvent);
- m_read = INVALID_HANDLE_VALUE;
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
- return result;
-}
-
-int PipeWindows::ReleaseWriteFileDescriptor() {
- if (!CanWrite())
- return PipeWindows::kInvalidDescriptor;
- int result = m_write_fd;
- m_write_fd = PipeWindows::kInvalidDescriptor;
- m_write = INVALID_HANDLE_VALUE;
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
- return result;
-}
-
-void PipeWindows::CloseReadFileDescriptor() {
- if (!CanRead())
- return;
-
- if (m_read_overlapped.hEvent)
- ::CloseHandle(m_read_overlapped.hEvent);
-
- _close(m_read_fd);
- m_read = INVALID_HANDLE_VALUE;
- m_read_fd = PipeWindows::kInvalidDescriptor;
- ZeroMemory(&m_read_overlapped, sizeof(m_read_overlapped));
-}
-
-void PipeWindows::CloseWriteFileDescriptor() {
- if (!CanWrite())
- return;
-
- _close(m_write_fd);
- m_write = INVALID_HANDLE_VALUE;
- m_write_fd = PipeWindows::kInvalidDescriptor;
- ZeroMemory(&m_write_overlapped, sizeof(m_write_overlapped));
-}
-
-void PipeWindows::Close() {
- CloseReadFileDescriptor();
- CloseWriteFileDescriptor();
-}
-
-Status PipeWindows::Delete(llvm::StringRef name) { return Status(); }
-
-bool PipeWindows::CanRead() const { return (m_read != INVALID_HANDLE_VALUE); }
-
-bool PipeWindows::CanWrite() const { return (m_write != INVALID_HANDLE_VALUE); }
-
-HANDLE
-PipeWindows::GetReadNativeHandle() { return m_read; }
-
-HANDLE
-PipeWindows::GetWriteNativeHandle() { return m_write; }
-
-Status PipeWindows::ReadWithTimeout(void *buf, size_t size,
- const std::chrono::microseconds &duration,
- size_t &bytes_read) {
- if (!CanRead())
- return Status(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- bytes_read = 0;
- DWORD sys_bytes_read = size;
- BOOL result = ::ReadFile(m_read, buf, sys_bytes_read, &sys_bytes_read,
- &m_read_overlapped);
- if (!result && GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- DWORD timeout = (duration == std::chrono::microseconds::zero())
- ? INFINITE
- : duration.count() * 1000;
- DWORD wait_result = ::WaitForSingleObject(m_read_overlapped.hEvent, timeout);
- if (wait_result != WAIT_OBJECT_0) {
- // The operation probably failed. However, if it timed out, we need to
- // cancel the I/O. Between the time we returned from WaitForSingleObject
- // and the time we call CancelIoEx, the operation may complete. If that
- // hapens, CancelIoEx will fail and return ERROR_NOT_FOUND. If that
- // happens, the original operation should be considered to have been
- // successful.
- bool failed = true;
- DWORD failure_error = ::GetLastError();
- if (wait_result == WAIT_TIMEOUT) {
- BOOL cancel_result = CancelIoEx(m_read, &m_read_overlapped);
- if (!cancel_result && GetLastError() == ERROR_NOT_FOUND)
- failed = false;
- }
- if (failed)
- return Status(failure_error, eErrorTypeWin32);
- }
-
- // Now we call GetOverlappedResult setting bWait to false, since we've
- // already waited as long as we're willing to.
- if (!GetOverlappedResult(m_read, &m_read_overlapped, &sys_bytes_read, FALSE))
- return Status(::GetLastError(), eErrorTypeWin32);
-
- bytes_read = sys_bytes_read;
- return Status();
-}
-
-Status PipeWindows::Write(const void *buf, size_t num_bytes,
- size_t &bytes_written) {
- if (!CanWrite())
- return Status(ERROR_INVALID_HANDLE, eErrorTypeWin32);
-
- DWORD sys_bytes_written = 0;
- BOOL write_result = ::WriteFile(m_write, buf, num_bytes, &sys_bytes_written,
- &m_write_overlapped);
- if (!write_result && GetLastError() != ERROR_IO_PENDING)
- return Status(::GetLastError(), eErrorTypeWin32);
-
- BOOL result = GetOverlappedResult(m_write, &m_write_overlapped,
- &sys_bytes_written, TRUE);
- if (!result)
- return Status(::GetLastError(), eErrorTypeWin32);
- return Status();
-}
diff --git a/source/Host/windows/ProcessLauncherWindows.cpp b/source/Host/windows/ProcessLauncherWindows.cpp
deleted file mode 100644
index a186c7177fdf..000000000000
--- a/source/Host/windows/ProcessLauncherWindows.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-//===-- ProcessLauncherWindows.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/windows/ProcessLauncherWindows.h"
-#include "lldb/Host/HostProcess.h"
-#include "lldb/Target/ProcessLaunchInfo.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/ConvertUTF.h"
-
-#include <string>
-#include <vector>
-
-using namespace lldb;
-using namespace lldb_private;
-
-namespace {
-void CreateEnvironmentBuffer(const Environment &env,
- std::vector<char> &buffer) {
- if (env.size() == 0)
- return;
-
- // Environment buffer is a null terminated list of null terminated strings
- for (const auto &KV : env) {
- std::wstring warg;
- if (llvm::ConvertUTF8toWide(Environment::compose(KV), warg)) {
- buffer.insert(buffer.end(), (char *)warg.c_str(),
- (char *)(warg.c_str() + warg.size() + 1));
- }
- }
- // One null wchar_t (to end the block) is two null bytes
- buffer.push_back(0);
- buffer.push_back(0);
-}
-}
-
-HostProcess
-ProcessLauncherWindows::LaunchProcess(const ProcessLaunchInfo &launch_info,
- Status &error) {
- error.Clear();
-
- std::string executable;
- std::string commandLine;
- std::vector<char> environment;
- STARTUPINFO startupinfo = {};
- PROCESS_INFORMATION pi = {};
-
- HANDLE stdin_handle = GetStdioHandle(launch_info, STDIN_FILENO);
- HANDLE stdout_handle = GetStdioHandle(launch_info, STDOUT_FILENO);
- HANDLE stderr_handle = GetStdioHandle(launch_info, STDERR_FILENO);
-
- startupinfo.cb = sizeof(startupinfo);
- startupinfo.dwFlags |= STARTF_USESTDHANDLES;
- startupinfo.hStdError =
- stderr_handle ? stderr_handle : ::GetStdHandle(STD_ERROR_HANDLE);
- startupinfo.hStdInput =
- stdin_handle ? stdin_handle : ::GetStdHandle(STD_INPUT_HANDLE);
- startupinfo.hStdOutput =
- stdout_handle ? stdout_handle : ::GetStdHandle(STD_OUTPUT_HANDLE);
-
- const char *hide_console_var =
- getenv("LLDB_LAUNCH_INFERIORS_WITHOUT_CONSOLE");
- if (hide_console_var &&
- llvm::StringRef(hide_console_var).equals_lower("true")) {
- startupinfo.dwFlags |= STARTF_USESHOWWINDOW;
- startupinfo.wShowWindow = SW_HIDE;
- }
-
- DWORD flags = CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
- if (launch_info.GetFlags().Test(eLaunchFlagDebug))
- flags |= DEBUG_ONLY_THIS_PROCESS;
-
- if (launch_info.GetFlags().Test(eLaunchFlagDisableSTDIO))
- flags &= ~CREATE_NEW_CONSOLE;
-
- LPVOID env_block = nullptr;
- ::CreateEnvironmentBuffer(launch_info.GetEnvironment(), environment);
- if (!environment.empty())
- env_block = environment.data();
-
- executable = launch_info.GetExecutableFile().GetPath();
- launch_info.GetArguments().GetQuotedCommandString(commandLine);
-
- 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) {
- // Call GetLastError before we make any other system calls.
- error.SetError(::GetLastError(), eErrorTypeWin32);
- }
-
- if (result) {
- // Do not call CloseHandle on pi.hProcess, since we want to pass that back
- // through the HostProcess.
- ::CloseHandle(pi.hThread);
- }
-
- if (stdin_handle)
- ::CloseHandle(stdin_handle);
- if (stdout_handle)
- ::CloseHandle(stdout_handle);
- if (stderr_handle)
- ::CloseHandle(stderr_handle);
-
- if (!result)
- return HostProcess();
-
- return HostProcess(pi.hProcess);
-}
-
-HANDLE
-ProcessLauncherWindows::GetStdioHandle(const ProcessLaunchInfo &launch_info,
- int fd) {
- const FileAction *action = launch_info.GetFileActionForFD(fd);
- if (action == nullptr)
- return NULL;
- SECURITY_ATTRIBUTES secattr = {};
- secattr.nLength = sizeof(SECURITY_ATTRIBUTES);
- secattr.bInheritHandle = TRUE;
-
- llvm::StringRef path = action->GetPath();
- DWORD access = 0;
- DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- DWORD create = 0;
- DWORD flags = 0;
- if (fd == STDIN_FILENO) {
- access = GENERIC_READ;
- create = OPEN_EXISTING;
- flags = FILE_ATTRIBUTE_READONLY;
- }
- if (fd == STDOUT_FILENO || fd == STDERR_FILENO) {
- access = GENERIC_WRITE;
- create = CREATE_ALWAYS;
- if (fd == STDERR_FILENO)
- flags = FILE_FLAG_WRITE_THROUGH;
- }
-
- 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;
-}
diff --git a/source/Host/windows/ProcessRunLock.cpp b/source/Host/windows/ProcessRunLock.cpp
deleted file mode 100644
index 64276917fc81..000000000000
--- a/source/Host/windows/ProcessRunLock.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- ProcessRunLock.cpp --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/ProcessRunLock.h"
-#include "lldb/Host/windows/windows.h"
-
-static PSRWLOCK GetLock(lldb::rwlock_t lock) {
- return static_cast<PSRWLOCK>(lock);
-}
-
-static bool ReadLock(lldb::rwlock_t rwlock) {
- ::AcquireSRWLockShared(GetLock(rwlock));
- return true;
-}
-
-static bool ReadUnlock(lldb::rwlock_t rwlock) {
- ::ReleaseSRWLockShared(GetLock(rwlock));
- return true;
-}
-
-static bool WriteLock(lldb::rwlock_t rwlock) {
- ::AcquireSRWLockExclusive(GetLock(rwlock));
- return true;
-}
-
-static bool WriteTryLock(lldb::rwlock_t rwlock) {
- return !!::TryAcquireSRWLockExclusive(GetLock(rwlock));
-}
-
-static bool WriteUnlock(lldb::rwlock_t rwlock) {
- ::ReleaseSRWLockExclusive(GetLock(rwlock));
- return true;
-}
-
-using namespace lldb_private;
-
-ProcessRunLock::ProcessRunLock() : m_running(false) {
- m_rwlock = new SRWLOCK;
- InitializeSRWLock(GetLock(m_rwlock));
-}
-
-ProcessRunLock::~ProcessRunLock() { delete static_cast<SRWLOCK *>(m_rwlock); }
-
-bool ProcessRunLock::ReadTryLock() {
- ::ReadLock(m_rwlock);
- if (m_running == false)
- return true;
- ::ReadUnlock(m_rwlock);
- return false;
-}
-
-bool ProcessRunLock::ReadUnlock() { return ::ReadUnlock(m_rwlock); }
-
-bool ProcessRunLock::SetRunning() {
- WriteLock(m_rwlock);
- m_running = true;
- WriteUnlock(m_rwlock);
- return true;
-}
-
-bool ProcessRunLock::TrySetRunning() {
- if (WriteTryLock(m_rwlock)) {
- bool was_running = m_running;
- m_running = true;
- WriteUnlock(m_rwlock);
- return !was_running;
- }
- return false;
-}
-
-bool ProcessRunLock::SetStopped() {
- WriteLock(m_rwlock);
- m_running = false;
- WriteUnlock(m_rwlock);
- return true;
-}
diff --git a/source/Host/windows/Windows.cpp b/source/Host/windows/Windows.cpp
deleted file mode 100644
index 9d0e70e6d126..000000000000
--- a/source/Host/windows/Windows.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-//===-- Windows.cpp ---------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// This file provides Windows support functions
-
-#include "lldb/Host/PosixApi.h"
-#include "lldb/Host/windows/windows.h"
-
-#include "llvm/Support/ConvertUTF.h"
-
-#include <assert.h>
-#include <cerrno>
-#include <ctype.h>
-#include <io.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace {
-bool utf8ToWide(const char *utf8, wchar_t *buf, size_t bufSize) {
- const llvm::UTF8 *sourceStart = reinterpret_cast<const llvm::UTF8 *>(utf8);
- size_t sourceLen = strlen(utf8) + 1 /* convert null too */;
- llvm::UTF16 *target = reinterpret_cast<llvm::UTF16 *>(buf);
- llvm::ConversionFlags flags = llvm::strictConversion;
- return llvm::ConvertUTF8toUTF16(&sourceStart, sourceStart + sourceLen, &target,
- target + bufSize, flags) == llvm::conversionOK;
-}
-
-bool wideToUtf8(const wchar_t *wide, char *buf, size_t bufSize) {
- const llvm::UTF16 *sourceStart = reinterpret_cast<const llvm::UTF16 *>(wide);
- size_t sourceLen = wcslen(wide) + 1 /* convert null too */;
- llvm::UTF8 *target = reinterpret_cast<llvm::UTF8 *>(buf);
- llvm::ConversionFlags flags = llvm::strictConversion;
- return llvm::ConvertUTF16toUTF8(&sourceStart, sourceStart + sourceLen, &target,
- target + bufSize, flags) == llvm::conversionOK;
-}
-}
-
-int vasprintf(char **ret, const char *fmt, va_list ap) {
- char *buf;
- int len;
- size_t buflen;
- va_list ap2;
-
-#if defined(_MSC_VER) || defined(__MINGW64)
- ap2 = ap;
- len = _vscprintf(fmt, ap2);
-#else
- va_copy(ap2, ap);
- len = vsnprintf(NULL, 0, fmt, ap2);
-#endif
-
- if (len >= 0 &&
- (buf = (char *)malloc((buflen = (size_t)(len + 1)))) != NULL) {
- len = vsnprintf(buf, buflen, fmt, ap);
- *ret = buf;
- } else {
- *ret = NULL;
- len = -1;
- }
-
- va_end(ap2);
- return len;
-}
-
-char *strcasestr(const char *s, const char *find) {
- char c, sc;
- size_t len;
-
- if ((c = *find++) != 0) {
- c = tolower((unsigned char)c);
- len = strlen(find);
- do {
- do {
- if ((sc = *s++) == 0)
- return 0;
- } while ((char)tolower((unsigned char)sc) != c);
- } while (strncasecmp(s, find, len) != 0);
- s--;
- }
- return ((char *)s);
-}
-
-char *realpath(const char *name, char *resolved) {
- 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.
- */
- wchar_t wideNameBuffer[PATH_MAX];
- wchar_t *wideName = wideNameBuffer;
- if (!utf8ToWide(name, wideName, PATH_MAX)) {
- errno = EINVAL;
- return NULL;
- }
-
- if (_waccess(wideName, 4) != 0)
- return NULL;
-
- /* 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.
- */
-
- 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.
- */
-
- wchar_t wideFullPathBuffer[PATH_MAX];
- wchar_t *wideFullPath;
- if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) ==
- NULL) {
- errno = ENAMETOOLONG;
- return NULL;
- }
-
- // 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);
-
- // Convert back to UTF-8
- if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX)) {
- errno = EINVAL;
- return NULL;
- }
-
- // Force drive to be upper case
- if (retname[1] == ':')
- retname[0] = toupper(retname[0]);
-
- return retname;
-}
-
-#ifdef _MSC_VER
-
-char *basename(char *path) {
- char *l1 = strrchr(path, '\\');
- char *l2 = strrchr(path, '/');
- if (l2 > l1)
- l1 = l2;
- if (!l1)
- return path; // no base name
- return &l1[1];
-}
-
-char *dirname(char *path) {
- char *l1 = strrchr(path, '\\');
- char *l2 = strrchr(path, '/');
- if (l2 > l1)
- l1 = l2;
- if (!l1)
- return NULL; // no dir name
- *l1 = 0;
- return path;
-}
-
-int strcasecmp(const char *s1, const char *s2) { return stricmp(s1, s2); }
-
-int strncasecmp(const char *s1, const char *s2, size_t n) {
- return strnicmp(s1, s2, n);
-}
-
-int usleep(uint32_t useconds) {
- Sleep(useconds / 1000);
- return 0;
-}
-
-#if _MSC_VER < 1900
-namespace lldb_private {
-int vsnprintf(char *buffer, size_t count, const char *format, va_list argptr) {
- int old_errno = errno;
- int r = ::vsnprintf(buffer, count, format, argptr);
- int new_errno = errno;
- buffer[count - 1] = '\0';
- if (r == -1 || r == count) {
- FILE *nul = fopen("nul", "w");
- int bytes_written = ::vfprintf(nul, format, argptr);
- fclose(nul);
- if (bytes_written < count)
- errno = new_errno;
- else {
- errno = old_errno;
- r = bytes_written;
- }
- }
- return r;
-}
-} // namespace lldb_private
-#endif
-
-#endif // _MSC_VER