diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:53:01 +0000 |
commit | ead246455adf1a215ec2715dad6533073a6beb4e (patch) | |
tree | f3f97a47d77053bf96fe74cdbd6fae74380e8a92 /source/Host/common | |
parent | fdb00c4408990a0a63ef7f496d809ce59f263bc5 (diff) |
Notes
Diffstat (limited to 'source/Host/common')
-rw-r--r-- | source/Host/common/Editline.cpp | 172 | ||||
-rw-r--r-- | source/Host/common/File.cpp | 410 | ||||
-rw-r--r-- | source/Host/common/FileCache.cpp | 38 | ||||
-rw-r--r-- | source/Host/common/FileSystem.cpp | 33 | ||||
-rw-r--r-- | source/Host/common/Host.cpp | 39 | ||||
-rw-r--r-- | source/Host/common/HostInfoBase.cpp | 21 | ||||
-rw-r--r-- | source/Host/common/HostNativeThreadBase.cpp | 3 | ||||
-rw-r--r-- | source/Host/common/LZMA.cpp | 146 | ||||
-rw-r--r-- | source/Host/common/MainLoop.cpp | 1 | ||||
-rw-r--r-- | source/Host/common/NativeProcessProtocol.cpp | 75 | ||||
-rw-r--r-- | source/Host/common/NativeRegisterContext.cpp | 32 | ||||
-rw-r--r-- | source/Host/common/Socket.cpp | 102 | ||||
-rw-r--r-- | source/Host/common/TCPSocket.cpp | 6 | ||||
-rw-r--r-- | source/Host/common/UDPSocket.cpp | 5 |
14 files changed, 667 insertions, 416 deletions
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp index d3a70aeaa3267..3e655244b107b 100644 --- a/source/Host/common/Editline.cpp +++ b/source/Host/common/Editline.cpp @@ -14,6 +14,7 @@ #include "lldb/Host/Editline.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/SelectHelper.h" @@ -863,26 +864,59 @@ unsigned char Editline::BufferEndCommand(int ch) { /// Prints completions and their descriptions to the given file. Only the /// completions in the interval [start, end) are printed. -static void PrintCompletion(FILE *output_file, size_t start, size_t end, - StringList &completions, StringList &descriptions) { - // This is an 'int' because of printf. - int max_len = 0; - - for (size_t i = start; i < end; i++) { - const char *completion_str = completions.GetStringAtIndex(i); - max_len = std::max((int)strlen(completion_str), max_len); +static void +PrintCompletion(FILE *output_file, + llvm::ArrayRef<CompletionResult::Completion> results, + size_t max_len) { + for (const CompletionResult::Completion &c : results) { + fprintf(output_file, "\t%-*s", (int)max_len, c.GetCompletion().c_str()); + if (!c.GetDescription().empty()) + fprintf(output_file, " -- %s", c.GetDescription().c_str()); + fprintf(output_file, "\n"); } +} + +static void +DisplayCompletions(::EditLine *editline, FILE *output_file, + llvm::ArrayRef<CompletionResult::Completion> results) { + assert(!results.empty()); - for (size_t i = start; i < end; i++) { - const char *completion_str = completions.GetStringAtIndex(i); - const char *description_str = descriptions.GetStringAtIndex(i); + fprintf(output_file, "\n" ANSI_CLEAR_BELOW "Available completions:\n"); + const size_t page_size = 40; + bool all = false; - if (completion_str) - fprintf(output_file, "\n\t%-*s", max_len, completion_str); + auto longest = + std::max_element(results.begin(), results.end(), [](auto &c1, auto &c2) { + return c1.GetCompletion().size() < c2.GetCompletion().size(); + }); - // Print the description if we got one. - if (description_str && strlen(description_str)) - fprintf(output_file, " -- %s", description_str); + const size_t max_len = longest->GetCompletion().size(); + + if (results.size() < page_size) { + PrintCompletion(output_file, results, max_len); + return; + } + + size_t cur_pos = 0; + while (cur_pos < results.size()) { + size_t remaining = results.size() - cur_pos; + size_t next_size = all ? remaining : std::min(page_size, remaining); + + PrintCompletion(output_file, results.slice(cur_pos, next_size), max_len); + + cur_pos += next_size; + + if (cur_pos >= results.size()) + break; + + fprintf(output_file, "More (Y/n/a): "); + char reply = 'n'; + int got_char = el_getc(editline, &reply); + fprintf(output_file, "\n"); + if (got_char == -1 || reply == 'n') + break; + if (reply == 'a') + all = true; } } @@ -891,74 +925,64 @@ unsigned char Editline::TabCommand(int ch) { return CC_ERROR; const LineInfo *line_info = el_line(m_editline); - StringList completions, descriptions; - int page_size = 40; - const int num_completions = m_completion_callback( - line_info->buffer, line_info->cursor, line_info->lastchar, - 0, // Don't skip any matches (start at match zero) - -1, // Get all the matches - completions, descriptions, m_completion_callback_baton); + llvm::StringRef line(line_info->buffer, + line_info->lastchar - line_info->buffer); + unsigned cursor_index = line_info->cursor - line_info->buffer; + CompletionResult result; + CompletionRequest request(line, cursor_index, result); - if (num_completions == 0) + m_completion_callback(request, m_completion_callback_baton); + + llvm::ArrayRef<CompletionResult::Completion> results = result.GetResults(); + + StringList completions; + result.GetMatches(completions); + + if (results.size() == 0) return CC_ERROR; - // if (num_completions == -1) - // { - // el_insertstr (m_editline, m_completion_key); - // return CC_REDISPLAY; - // } - // else - if (num_completions == -2) { - // Replace the entire line with the first string... - el_deletestr(m_editline, line_info->cursor - line_info->buffer); - el_insertstr(m_editline, completions.GetStringAtIndex(0)); + + if (results.size() == 1) { + CompletionResult::Completion completion = results.front(); + switch (completion.GetMode()) { + case CompletionMode::Normal: { + std::string to_add = completion.GetCompletion(); + to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); + if (request.GetParsedArg().IsQuoted()) + to_add.push_back(request.GetParsedArg().GetQuoteChar()); + to_add.push_back(' '); + el_insertstr(m_editline, to_add.c_str()); + break; + } + case CompletionMode::Partial: { + std::string to_add = completion.GetCompletion(); + to_add = to_add.substr(request.GetCursorArgumentPrefix().size()); + el_insertstr(m_editline, to_add.c_str()); + break; + } + case CompletionMode::RewriteLine: { + el_deletestr(m_editline, line_info->cursor - line_info->buffer); + el_insertstr(m_editline, completion.GetCompletion().c_str()); + break; + } + } return CC_REDISPLAY; } // If we get a longer match display that first. - const char *completion_str = completions.GetStringAtIndex(0); - if (completion_str != nullptr && *completion_str != '\0') { - el_insertstr(m_editline, completion_str); + std::string longest_prefix = completions.LongestCommonPrefix(); + if (!longest_prefix.empty()) + longest_prefix = + longest_prefix.substr(request.GetCursorArgumentPrefix().size()); + if (!longest_prefix.empty()) { + el_insertstr(m_editline, longest_prefix.c_str()); return CC_REDISPLAY; } - if (num_completions > 1) { - int num_elements = num_completions + 1; - fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:"); - if (num_completions < page_size) { - PrintCompletion(m_output_file, 1, num_elements, completions, - descriptions); - fprintf(m_output_file, "\n"); - } else { - int cur_pos = 1; - char reply; - int got_char; - while (cur_pos < num_elements) { - int endpoint = cur_pos + page_size; - if (endpoint > num_elements) - endpoint = num_elements; - - PrintCompletion(m_output_file, cur_pos, endpoint, completions, - descriptions); - cur_pos = endpoint; - - if (cur_pos >= num_elements) { - fprintf(m_output_file, "\n"); - break; - } - - fprintf(m_output_file, "\nMore (Y/n/a): "); - reply = 'n'; - got_char = el_getc(m_editline, &reply); - if (got_char == -1 || reply == 'n') - break; - if (reply == 'a') - page_size = num_elements - cur_pos; - } - } - DisplayInput(); - MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); - } + DisplayCompletions(m_editline, m_output_file, results); + + DisplayInput(); + MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor); return CC_REDISPLAY; } diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp index c8c8d7a0d496c..9dae24d766f62 100644 --- a/source/Host/common/File.cpp +++ b/source/Host/common/File.cpp @@ -37,8 +37,10 @@ using namespace lldb; using namespace lldb_private; +using llvm::Expected; -static const char *GetStreamOpenModeFromOptions(uint32_t options) { +Expected<const char *> +File::GetStreamOpenModeFromOptions(File::OpenOptions options) { if (options & File::eOpenOptionAppend) { if (options & File::eOpenOptionRead) { if (options & File::eOpenOptionCanCreateNewOnly) @@ -65,15 +67,188 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) { } else if (options & File::eOpenOptionWrite) { return "w"; } - return nullptr; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "invalid options, cannot convert to mode string"); +} + +Expected<File::OpenOptions> File::GetOptionsFromMode(llvm::StringRef mode) { + OpenOptions opts = + llvm::StringSwitch<OpenOptions>(mode) + .Cases("r", "rb", eOpenOptionRead) + .Cases("w", "wb", eOpenOptionWrite) + .Cases("a", "ab", + eOpenOptionWrite | eOpenOptionAppend | eOpenOptionCanCreate) + .Cases("r+", "rb+", "r+b", eOpenOptionRead | eOpenOptionWrite) + .Cases("w+", "wb+", "w+b", + eOpenOptionRead | eOpenOptionWrite | eOpenOptionCanCreate | + eOpenOptionTruncate) + .Cases("a+", "ab+", "a+b", + eOpenOptionRead | eOpenOptionWrite | eOpenOptionAppend | + eOpenOptionCanCreate) + .Default(OpenOptions()); + if (opts) + return opts; + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "invalid mode, cannot convert to File::OpenOptions"); } int File::kInvalidDescriptor = -1; FILE *File::kInvalidStream = nullptr; -File::~File() { Close(); } +Status File::Read(void *buf, size_t &num_bytes) { + return std::error_code(ENOTSUP, std::system_category()); +} +Status File::Write(const void *buf, size_t &num_bytes) { + return std::error_code(ENOTSUP, std::system_category()); +} + +bool File::IsValid() const { return false; } + +Status File::Close() { return Flush(); } + +IOObject::WaitableHandle File::GetWaitableHandle() { + return IOObject::kInvalidHandleValue; +} -int File::GetDescriptor() const { +Status File::GetFileSpec(FileSpec &file_spec) const { + file_spec.Clear(); + return std::error_code(ENOTSUP, std::system_category()); +} + +int File::GetDescriptor() const { return kInvalidDescriptor; } + +FILE *File::GetStream() { return nullptr; } + +off_t File::SeekFromStart(off_t offset, Status *error_ptr) { + if (error_ptr) + *error_ptr = std::error_code(ENOTSUP, std::system_category()); + return -1; +} + +off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) { + if (error_ptr) + *error_ptr = std::error_code(ENOTSUP, std::system_category()); + return -1; +} + +off_t File::SeekFromEnd(off_t offset, Status *error_ptr) { + if (error_ptr) + *error_ptr = std::error_code(ENOTSUP, std::system_category()); + return -1; +} + +Status File::Read(void *dst, size_t &num_bytes, off_t &offset) { + return std::error_code(ENOTSUP, std::system_category()); +} + +Status File::Write(const void *src, size_t &num_bytes, off_t &offset) { + return std::error_code(ENOTSUP, std::system_category()); +} + +Status File::Flush() { return Status(); } + +Status File::Sync() { return Flush(); } + +void File::CalculateInteractiveAndTerminal() { + const int fd = GetDescriptor(); + if (!DescriptorIsValid(fd)) { + m_is_interactive = eLazyBoolNo; + m_is_real_terminal = eLazyBoolNo; + m_supports_colors = eLazyBoolNo; + return; + } + m_is_interactive = eLazyBoolNo; + m_is_real_terminal = eLazyBoolNo; +#if defined(_WIN32) + if (_isatty(fd)) { + m_is_interactive = eLazyBoolYes; + m_is_real_terminal = eLazyBoolYes; +#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) + m_supports_colors = eLazyBoolYes; +#endif + } +#else + if (isatty(fd)) { + m_is_interactive = eLazyBoolYes; + struct winsize window_size; + if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) { + if (window_size.ws_col > 0) { + m_is_real_terminal = eLazyBoolYes; + if (llvm::sys::Process::FileDescriptorHasColors(fd)) + m_supports_colors = eLazyBoolYes; + } + } + } +#endif +} + +bool File::GetIsInteractive() { + if (m_is_interactive == eLazyBoolCalculate) + CalculateInteractiveAndTerminal(); + return m_is_interactive == eLazyBoolYes; +} + +bool File::GetIsRealTerminal() { + if (m_is_real_terminal == eLazyBoolCalculate) + CalculateInteractiveAndTerminal(); + return m_is_real_terminal == eLazyBoolYes; +} + +bool File::GetIsTerminalWithColors() { + if (m_supports_colors == eLazyBoolCalculate) + CalculateInteractiveAndTerminal(); + return m_supports_colors == eLazyBoolYes; +} + +size_t File::Printf(const char *format, ...) { + va_list args; + va_start(args, format); + size_t result = PrintfVarArg(format, args); + va_end(args); + return result; +} + +size_t File::PrintfVarArg(const char *format, va_list args) { + size_t result = 0; + char *s = nullptr; + result = vasprintf(&s, format, args); + if (s != nullptr) { + if (result > 0) { + size_t s_len = result; + Write(s, s_len); + result = s_len; + } + free(s); + } + return result; +} + +Expected<File::OpenOptions> File::GetOptions() const { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "GetOptions() not implemented for this File class"); +} + +uint32_t File::GetPermissions(Status &error) const { + int fd = GetDescriptor(); + if (!DescriptorIsValid(fd)) { + error = std::error_code(ENOTSUP, std::system_category()); + return 0; + } + struct stat file_stats; + if (::fstat(fd, &file_stats) == -1) { + error.SetErrorToErrno(); + return 0; + } + error.Clear(); + return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); +} + +Expected<File::OpenOptions> NativeFile::GetOptions() const { return m_options; } + +int NativeFile::GetDescriptor() const { if (DescriptorIsValid()) return m_descriptor; @@ -91,21 +266,18 @@ int File::GetDescriptor() const { return kInvalidDescriptor; } -IOObject::WaitableHandle File::GetWaitableHandle() { return m_descriptor; } - -void File::SetDescriptor(int fd, bool transfer_ownership) { - if (IsValid()) - Close(); - m_descriptor = fd; - m_should_close_fd = transfer_ownership; +IOObject::WaitableHandle NativeFile::GetWaitableHandle() { + return GetDescriptor(); } -FILE *File::GetStream() { +FILE *NativeFile::GetStream() { if (!StreamIsValid()) { if (DescriptorIsValid()) { - const char *mode = GetStreamOpenModeFromOptions(m_options); - if (mode) { - if (!m_should_close_fd) { + auto mode = GetStreamOpenModeFromOptions(m_options); + if (!mode) + llvm::consumeError(mode.takeError()); + else { + if (!m_own_descriptor) { // We must duplicate the file descriptor if we don't own it because when you // call fdopen, the stream will own the fd #ifdef _WIN32 @@ -113,18 +285,18 @@ FILE *File::GetStream() { #else m_descriptor = dup(GetDescriptor()); #endif - m_should_close_fd = true; + m_own_descriptor = true; } - m_stream = - llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode); + m_stream = llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, + mode.get()); // If we got a stream, then we own the stream and should no longer own // the descriptor because fclose() will close it for us if (m_stream) { m_own_stream = true; - m_should_close_fd = false; + m_own_descriptor = false; } } } @@ -132,60 +304,32 @@ FILE *File::GetStream() { return m_stream; } -void File::SetStream(FILE *fh, bool transfer_ownership) { - if (IsValid()) - Close(); - m_stream = fh; - m_own_stream = transfer_ownership; -} - -uint32_t File::GetPermissions(Status &error) const { - int fd = GetDescriptor(); - if (fd != kInvalidDescriptor) { - struct stat file_stats; - if (::fstat(fd, &file_stats) == -1) - error.SetErrorToErrno(); - else { - error.Clear(); - return file_stats.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO); - } - } else { - error.SetErrorString("invalid file descriptor"); - } - return 0; -} - -Status File::Close() { +Status NativeFile::Close() { Status error; - if (StreamIsValid() && m_own_stream) { - if (::fclose(m_stream) == EOF) - error.SetErrorToErrno(); + if (StreamIsValid()) { + if (m_own_stream) { + if (::fclose(m_stream) == EOF) + error.SetErrorToErrno(); + } else { + if (::fflush(m_stream) == EOF) + error.SetErrorToErrno(); + } } - - if (DescriptorIsValid() && m_should_close_fd) { + if (DescriptorIsValid() && m_own_descriptor) { if (::close(m_descriptor) != 0) error.SetErrorToErrno(); } m_descriptor = kInvalidDescriptor; m_stream = kInvalidStream; - m_options = 0; + m_options = OpenOptions(0); m_own_stream = false; - m_should_close_fd = false; + m_own_descriptor = false; m_is_interactive = eLazyBoolCalculate; m_is_real_terminal = eLazyBoolCalculate; return error; } -void File::Clear() { - m_stream = nullptr; - m_descriptor = kInvalidDescriptor; - m_options = 0; - m_own_stream = false; - m_is_interactive = m_supports_colors = m_is_real_terminal = - eLazyBoolCalculate; -} - -Status File::GetFileSpec(FileSpec &file_spec) const { +Status NativeFile::GetFileSpec(FileSpec &file_spec) const { Status error; #ifdef F_GETPATH if (IsValid()) { @@ -212,7 +356,8 @@ Status File::GetFileSpec(FileSpec &file_spec) const { } } #else - error.SetErrorString("File::GetFileSpec is not supported on this platform"); + error.SetErrorString( + "NativeFile::GetFileSpec is not supported on this platform"); #endif if (error.Fail()) @@ -220,7 +365,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const { return error; } -off_t File::SeekFromStart(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromStart(off_t offset, Status *error_ptr) { off_t result = 0; if (DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_SET); @@ -246,7 +391,7 @@ off_t File::SeekFromStart(off_t offset, Status *error_ptr) { return result; } -off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromCurrent(off_t offset, Status *error_ptr) { off_t result = -1; if (DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_CUR); @@ -272,7 +417,7 @@ off_t File::SeekFromCurrent(off_t offset, Status *error_ptr) { return result; } -off_t File::SeekFromEnd(off_t offset, Status *error_ptr) { +off_t NativeFile::SeekFromEnd(off_t offset, Status *error_ptr) { off_t result = -1; if (DescriptorIsValid()) { result = ::lseek(m_descriptor, offset, SEEK_END); @@ -298,7 +443,7 @@ off_t File::SeekFromEnd(off_t offset, Status *error_ptr) { return result; } -Status File::Flush() { +Status NativeFile::Flush() { Status error; if (StreamIsValid()) { if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF) @@ -309,7 +454,7 @@ Status File::Flush() { return error; } -Status File::Sync() { +Status NativeFile::Sync() { Status error; if (DescriptorIsValid()) { #ifdef _WIN32 @@ -332,7 +477,7 @@ Status File::Sync() { #define MAX_WRITE_SIZE INT_MAX #endif -Status File::Read(void *buf, size_t &num_bytes) { +Status NativeFile::Read(void *buf, size_t &num_bytes) { Status error; #if defined(MAX_READ_SIZE) @@ -391,7 +536,7 @@ Status File::Read(void *buf, size_t &num_bytes) { return error; } -Status File::Write(const void *buf, size_t &num_bytes) { +Status NativeFile::Write(const void *buf, size_t &num_bytes) { Status error; #if defined(MAX_WRITE_SIZE) @@ -453,7 +598,7 @@ Status File::Write(const void *buf, size_t &num_bytes) { return error; } -Status File::Read(void *buf, size_t &num_bytes, off_t &offset) { +Status NativeFile::Read(void *buf, size_t &num_bytes, off_t &offset) { Status error; #if defined(MAX_READ_SIZE) @@ -513,51 +658,7 @@ Status File::Read(void *buf, size_t &num_bytes, off_t &offset) { return error; } -Status File::Read(size_t &num_bytes, off_t &offset, bool null_terminate, - DataBufferSP &data_buffer_sp) { - Status error; - - if (num_bytes > 0) { - int fd = GetDescriptor(); - if (fd != kInvalidDescriptor) { - struct stat file_stats; - if (::fstat(fd, &file_stats) == 0) { - if (file_stats.st_size > offset) { - const size_t bytes_left = file_stats.st_size - offset; - if (num_bytes > bytes_left) - num_bytes = bytes_left; - - size_t num_bytes_plus_nul_char = num_bytes + (null_terminate ? 1 : 0); - std::unique_ptr<DataBufferHeap> data_heap_up; - data_heap_up.reset(new DataBufferHeap()); - data_heap_up->SetByteSize(num_bytes_plus_nul_char); - - if (data_heap_up) { - error = Read(data_heap_up->GetBytes(), num_bytes, offset); - if (error.Success()) { - // Make sure we read exactly what we asked for and if we got - // less, adjust the array - if (num_bytes_plus_nul_char < data_heap_up->GetByteSize()) - data_heap_up->SetByteSize(num_bytes_plus_nul_char); - data_buffer_sp.reset(data_heap_up.release()); - return error; - } - } - } else - error.SetErrorString("file is empty"); - } else - error.SetErrorToErrno(); - } else - error.SetErrorString("invalid file handle"); - } else - error.SetErrorString("invalid file handle"); - - num_bytes = 0; - data_buffer_sp.reset(); - return error; -} - -Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) { +Status NativeFile::Write(const void *buf, size_t &num_bytes, off_t &offset) { Status error; #if defined(MAX_WRITE_SIZE) @@ -621,36 +722,15 @@ Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) { return error; } -// Print some formatted output to the stream. -size_t File::Printf(const char *format, ...) { - va_list args; - va_start(args, format); - size_t result = PrintfVarArg(format, args); - va_end(args); - return result; -} - -// Print some formatted output to the stream. -size_t File::PrintfVarArg(const char *format, va_list args) { - size_t result = 0; - if (DescriptorIsValid()) { - char *s = nullptr; - result = vasprintf(&s, format, args); - if (s != nullptr) { - if (result > 0) { - size_t s_len = result; - Write(s, s_len); - result = s_len; - } - free(s); - } - } else if (StreamIsValid()) { - result = ::vfprintf(m_stream, format, args); +size_t NativeFile::PrintfVarArg(const char *format, va_list args) { + if (StreamIsValid()) { + return ::vfprintf(m_stream, format, args); + } else { + return File::PrintfVarArg(format, args); } - return result; } -mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) { +mode_t File::ConvertOpenOptionsForPOSIXOpen(OpenOptions open_options) { mode_t mode = 0; if (open_options & eOpenOptionRead && open_options & eOpenOptionWrite) mode |= O_RDWR; @@ -674,49 +754,5 @@ mode_t File::ConvertOpenOptionsForPOSIXOpen(uint32_t open_options) { return mode; } -void File::CalculateInteractiveAndTerminal() { - const int fd = GetDescriptor(); - if (fd >= 0) { - m_is_interactive = eLazyBoolNo; - m_is_real_terminal = eLazyBoolNo; -#if defined(_WIN32) - if (_isatty(fd)) { - m_is_interactive = eLazyBoolYes; - m_is_real_terminal = eLazyBoolYes; -#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) - m_supports_colors = eLazyBoolYes; -#endif - } -#else - if (isatty(fd)) { - m_is_interactive = eLazyBoolYes; - struct winsize window_size; - if (::ioctl(fd, TIOCGWINSZ, &window_size) == 0) { - if (window_size.ws_col > 0) { - m_is_real_terminal = eLazyBoolYes; - if (llvm::sys::Process::FileDescriptorHasColors(fd)) - m_supports_colors = eLazyBoolYes; - } - } - } -#endif - } -} - -bool File::GetIsInteractive() { - if (m_is_interactive == eLazyBoolCalculate) - CalculateInteractiveAndTerminal(); - return m_is_interactive == eLazyBoolYes; -} - -bool File::GetIsRealTerminal() { - if (m_is_real_terminal == eLazyBoolCalculate) - CalculateInteractiveAndTerminal(); - return m_is_real_terminal == eLazyBoolYes; -} - -bool File::GetIsTerminalWithColors() { - if (m_supports_colors == eLazyBoolCalculate) - CalculateInteractiveAndTerminal(); - return m_supports_colors == eLazyBoolYes; -} +char File::ID = 0; +char NativeFile::ID = 0; diff --git a/source/Host/common/FileCache.cpp b/source/Host/common/FileCache.cpp index 4bd3efda7fb0e..d9dcad992c33a 100644 --- a/source/Host/common/FileCache.cpp +++ b/source/Host/common/FileCache.cpp @@ -23,18 +23,20 @@ FileCache &FileCache::GetInstance() { return *m_instance; } -lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, - uint32_t mode, Status &error) { +lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, + File::OpenOptions flags, uint32_t mode, + Status &error) { if (!file_spec) { error.SetErrorString("empty path"); return UINT64_MAX; } - FileSP file_sp(new File()); - error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode); - if (!file_sp->IsValid()) + auto file = FileSystem::Instance().Open(file_spec, flags, mode); + if (!file) { + error = file.takeError(); return UINT64_MAX; - lldb::user_id_t fd = file_sp->GetDescriptor(); - m_cache[fd] = file_sp; + } + lldb::user_id_t fd = file.get()->GetDescriptor(); + m_cache[fd] = std::move(file.get()); return fd; } @@ -48,12 +50,12 @@ bool FileCache::CloseFile(lldb::user_id_t fd, Status &error) { error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); return false; } - FileSP file_sp = pos->second; - if (!file_sp) { + FileUP &file_up = pos->second; + if (!file_up) { error.SetErrorString("invalid host backing file"); return false; } - error = file_sp->Close(); + error = file_up->Close(); m_cache.erase(pos); return error.Success(); } @@ -70,16 +72,16 @@ uint64_t FileCache::WriteFile(lldb::user_id_t fd, uint64_t offset, error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); return false; } - FileSP file_sp = pos->second; - if (!file_sp) { + FileUP &file_up = pos->second; + if (!file_up) { error.SetErrorString("invalid host backing file"); return UINT64_MAX; } - if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || + if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || error.Fail()) return UINT64_MAX; size_t bytes_written = src_len; - error = file_sp->Write(src, bytes_written); + error = file_up->Write(src, bytes_written); if (error.Fail()) return UINT64_MAX; return bytes_written; @@ -96,16 +98,16 @@ uint64_t FileCache::ReadFile(lldb::user_id_t fd, uint64_t offset, void *dst, error.SetErrorStringWithFormat("invalid host file descriptor %" PRIu64, fd); return false; } - FileSP file_sp = pos->second; - if (!file_sp) { + FileUP &file_up = pos->second; + if (!file_up) { error.SetErrorString("invalid host backing file"); return UINT64_MAX; } - if (static_cast<uint64_t>(file_sp->SeekFromStart(offset, &error)) != offset || + if (static_cast<uint64_t>(file_up->SeekFromStart(offset, &error)) != offset || error.Fail()) return UINT64_MAX; size_t bytes_read = dst_len; - error = file_sp->Read(dst, bytes_read); + error = file_up->Read(dst, bytes_read); if (error.Fail()) return UINT64_MAX; return bytes_read; diff --git a/source/Host/common/FileSystem.cpp b/source/Host/common/FileSystem.cpp index d5ac05bd447c4..2db5bff3207fd 100644 --- a/source/Host/common/FileSystem.cpp +++ b/source/Host/common/FileSystem.cpp @@ -49,7 +49,7 @@ void FileSystem::Initialize() { InstanceImpl().emplace(); } -void FileSystem::Initialize(FileCollector &collector) { +void FileSystem::Initialize(std::shared_ptr<FileCollector> collector) { lldbassert(!InstanceImpl() && "Already initialized."); InstanceImpl().emplace(collector); } @@ -280,7 +280,7 @@ std::shared_ptr<DataBufferLLVM> FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, uint64_t offset) { if (m_collector) - m_collector->AddFile(path); + m_collector->addFile(path); const bool is_volatile = !IsLocal(path); const ErrorOr<std::string> external_path = GetExternalPath(path); @@ -415,13 +415,11 @@ static mode_t GetOpenMode(uint32_t permissions) { return mode; } -Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options, - uint32_t permissions, bool should_close_fd) { +Expected<FileUP> FileSystem::Open(const FileSpec &file_spec, + File::OpenOptions options, + uint32_t permissions, bool should_close_fd) { if (m_collector) - m_collector->AddFile(file_spec); - - if (File.IsValid()) - File.Close(); + m_collector->addFile(file_spec.GetPath()); const int open_flags = GetOpenFlags(options); const mode_t open_mode = @@ -429,20 +427,19 @@ Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options, auto path = GetExternalPath(file_spec); if (!path) - return Status(path.getError()); + return errorCodeToError(path.getError()); int descriptor = llvm::sys::RetryAfterSignal( -1, OpenWithFS, *this, path->c_str(), open_flags, open_mode); - Status error; - if (!File::DescriptorIsValid(descriptor)) { - File.SetDescriptor(descriptor, false); - error.SetErrorToErrno(); - } else { - File.SetDescriptor(descriptor, should_close_fd); - File.SetOptions(options); - } - return error; + if (!File::DescriptorIsValid(descriptor)) + return llvm::errorCodeToError( + std::error_code(errno, std::system_category())); + + auto file = std::unique_ptr<File>( + new NativeFile(descriptor, options, should_close_fd)); + assert(file->IsValid()); + return std::move(file); } ErrorOr<std::string> FileSystem::GetExternalPath(const llvm::Twine &path) { diff --git a/source/Host/common/Host.cpp b/source/Host/common/Host.cpp index 3ba9ab7f21f36..8e210c7e5fa56 100644 --- a/source/Host/common/Host.cpp +++ b/source/Host/common/Host.cpp @@ -164,8 +164,7 @@ static bool CheckForMonitorCancellation() { static thread_result_t MonitorChildProcessThreadFunction(void *arg) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); const char *function = __FUNCTION__; - if (log) - log->Printf("%s (arg = %p) thread starting...", function, arg); + LLDB_LOGF(log, "%s (arg = %p) thread starting...", function, arg); MonitorInfo *info = (MonitorInfo *)arg; @@ -193,9 +192,8 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { while (1) { log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - if (log) - log->Printf("%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", - function, pid, options); + LLDB_LOGF(log, "%s ::waitpid (pid = %" PRIi32 ", &status, options = %i)...", + function, pid, options); if (CheckForMonitorCancellation()) break; @@ -245,12 +243,12 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { #endif log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - if (log) - log->Printf("%s ::waitpid (pid = %" PRIi32 - ", &status, options = %i) => pid = %" PRIi32 - ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", - function, pid, options, wait_pid, status, status_cstr, - signal, exit_status); + LLDB_LOGF(log, + "%s ::waitpid (pid = %" PRIi32 + ", &status, options = %i) => pid = %" PRIi32 + ", status = 0x%8.8x (%s), signal = %i, exit_state = %i", + function, pid, options, wait_pid, status, status_cstr, signal, + exit_status); if (exited || (signal != 0 && monitor_signals)) { bool callback_return = false; @@ -259,18 +257,18 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { // If our process exited, then this thread should exit if (exited && wait_pid == abs(pid)) { - if (log) - log->Printf("%s (arg = %p) thread exiting because pid received " - "exit signal...", - __FUNCTION__, arg); + LLDB_LOGF(log, + "%s (arg = %p) thread exiting because pid received " + "exit signal...", + __FUNCTION__, arg); break; } // If the callback returns true, it means this process should exit if (callback_return) { - if (log) - log->Printf("%s (arg = %p) thread exiting because callback " - "returned true...", - __FUNCTION__, arg); + LLDB_LOGF(log, + "%s (arg = %p) thread exiting because callback " + "returned true...", + __FUNCTION__, arg); break; } } @@ -279,8 +277,7 @@ static thread_result_t MonitorChildProcessThreadFunction(void *arg) { } log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); - if (log) - log->Printf("%s (arg = %p) thread exiting...", __FUNCTION__, arg); + LLDB_LOGF(log, "%s (arg = %p) thread exiting...", __FUNCTION__, arg); return nullptr; } diff --git a/source/Host/common/HostInfoBase.cpp b/source/Host/common/HostInfoBase.cpp index 130f0eb8ac8dd..3765f36fc79ae 100644 --- a/source/Host/common/HostInfoBase.cpp +++ b/source/Host/common/HostInfoBase.cpp @@ -221,25 +221,24 @@ bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec, return false; std::string raw_path = lldb_file_spec.GetPath(); - if (log) - log->Printf("HostInfo::%s() attempting to " - "derive the path %s relative to liblldb install path: %s", - __FUNCTION__, dir.data(), raw_path.c_str()); + LLDB_LOGF(log, + "HostInfo::%s() attempting to " + "derive the path %s relative to liblldb install path: %s", + __FUNCTION__, dir.data(), raw_path.c_str()); // Drop bin (windows) or lib llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path); if (parent_path.empty()) { - if (log) - log->Printf("HostInfo::%s() failed to find liblldb within the shared " - "lib path", - __FUNCTION__); + LLDB_LOGF(log, + "HostInfo::%s() failed to find liblldb within the shared " + "lib path", + __FUNCTION__); return false; } raw_path = (parent_path + dir).str(); - if (log) - log->Printf("HostInfo::%s() derived the path as: %s", __FUNCTION__, - raw_path.c_str()); + LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__, + raw_path.c_str()); file_spec.GetDirectory().SetString(raw_path); return (bool)file_spec.GetDirectory(); } diff --git a/source/Host/common/HostNativeThreadBase.cpp b/source/Host/common/HostNativeThreadBase.cpp index a5f876a7232af..fe7d85acaf118 100644 --- a/source/Host/common/HostNativeThreadBase.cpp +++ b/source/Host/common/HostNativeThreadBase.cpp @@ -62,8 +62,7 @@ HostNativeThreadBase::ThreadCreateTrampoline(lldb::thread_arg_t arg) { thread_arg_t thread_arg = info->thread_arg; Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); - if (log) - log->Printf("thread created"); + LLDB_LOGF(log, "thread created"); delete info; return thread_fptr(thread_arg); diff --git a/source/Host/common/LZMA.cpp b/source/Host/common/LZMA.cpp new file mode 100644 index 0000000000000..02be8a09df66a --- /dev/null +++ b/source/Host/common/LZMA.cpp @@ -0,0 +1,146 @@ +//===-- LZMA.cpp ------------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/Config.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +#if LLDB_ENABLE_LZMA +#include <lzma.h> +#endif // LLDB_ENABLE_LZMA + +namespace lldb_private { + +namespace lzma { + +#if !LLDB_ENABLE_LZMA +bool isAvailable() { return false; } +llvm::Expected<uint64_t> +getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) { + llvm_unreachable("lzma::getUncompressedSize is unavailable"); +} + +llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer, + llvm::SmallVectorImpl<uint8_t> &Uncompressed) { + llvm_unreachable("lzma::uncompress is unavailable"); +} + +#else // LLDB_ENABLE_LZMA + +bool isAvailable() { return true; } + +static const char *convertLZMACodeToString(lzma_ret Code) { + switch (Code) { + case LZMA_STREAM_END: + return "lzma error: LZMA_STREAM_END"; + case LZMA_NO_CHECK: + return "lzma error: LZMA_NO_CHECK"; + case LZMA_UNSUPPORTED_CHECK: + return "lzma error: LZMA_UNSUPPORTED_CHECK"; + case LZMA_GET_CHECK: + return "lzma error: LZMA_GET_CHECK"; + case LZMA_MEM_ERROR: + return "lzma error: LZMA_MEM_ERROR"; + case LZMA_MEMLIMIT_ERROR: + return "lzma error: LZMA_MEMLIMIT_ERROR"; + case LZMA_FORMAT_ERROR: + return "lzma error: LZMA_FORMAT_ERROR"; + case LZMA_OPTIONS_ERROR: + return "lzma error: LZMA_OPTIONS_ERROR"; + case LZMA_DATA_ERROR: + return "lzma error: LZMA_DATA_ERROR"; + case LZMA_BUF_ERROR: + return "lzma error: LZMA_BUF_ERROR"; + case LZMA_PROG_ERROR: + return "lzma error: LZMA_PROG_ERROR"; + default: + llvm_unreachable("unknown or unexpected lzma status code"); + } +} + +llvm::Expected<uint64_t> +getUncompressedSize(llvm::ArrayRef<uint8_t> InputBuffer) { + lzma_stream_flags opts{}; + if (InputBuffer.size() < LZMA_STREAM_HEADER_SIZE) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "size of xz-compressed blob (%lu bytes) is smaller than the " + "LZMA_STREAM_HEADER_SIZE (%lu bytes)", + InputBuffer.size(), LZMA_STREAM_HEADER_SIZE); + } + + // Decode xz footer. + lzma_ret xzerr = lzma_stream_footer_decode( + &opts, InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE).data()); + if (xzerr != LZMA_OK) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "lzma_stream_footer_decode()=%s", + convertLZMACodeToString(xzerr)); + } + if (InputBuffer.size() < (opts.backward_size + LZMA_STREAM_HEADER_SIZE)) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "xz-compressed buffer size (%lu bytes) too small (required at " + "least %lu bytes) ", + InputBuffer.size(), (opts.backward_size + LZMA_STREAM_HEADER_SIZE)); + } + + // Decode xz index. + lzma_index *xzindex; + uint64_t memlimit(UINT64_MAX); + size_t inpos = 0; + xzerr = lzma_index_buffer_decode( + &xzindex, &memlimit, nullptr, + InputBuffer.take_back(LZMA_STREAM_HEADER_SIZE + opts.backward_size) + .data(), + &inpos, InputBuffer.size()); + if (xzerr != LZMA_OK) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "lzma_index_buffer_decode()=%s", + convertLZMACodeToString(xzerr)); + } + + // Get size of uncompressed file to construct an in-memory buffer of the + // same size on the calling end (if needed). + uint64_t uncompressedSize = lzma_index_uncompressed_size(xzindex); + + // Deallocate xz index as it is no longer needed. + lzma_index_end(xzindex, nullptr); + + return uncompressedSize; +} + +llvm::Error uncompress(llvm::ArrayRef<uint8_t> InputBuffer, + llvm::SmallVectorImpl<uint8_t> &Uncompressed) { + llvm::Expected<uint64_t> uncompressedSize = getUncompressedSize(InputBuffer); + + if (auto err = uncompressedSize.takeError()) + return err; + + Uncompressed.resize(*uncompressedSize); + + // Decompress xz buffer to buffer. + uint64_t memlimit = UINT64_MAX; + size_t inpos = 0; + size_t outpos = 0; + lzma_ret ret = lzma_stream_buffer_decode( + &memlimit, 0, nullptr, InputBuffer.data(), &inpos, InputBuffer.size(), + Uncompressed.data(), &outpos, Uncompressed.size()); + if (ret != LZMA_OK) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "lzma_stream_buffer_decode()=%s", + convertLZMACodeToString(ret)); + } + + return llvm::Error::success(); +} + +#endif // LLDB_ENABLE_LZMA + +} // end of namespace lzma +} // namespace lldb_private diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp index 1ce09a84671c5..6f774451c8a44 100644 --- a/source/Host/common/MainLoop.cpp +++ b/source/Host/common/MainLoop.cpp @@ -320,6 +320,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { // Even if using kqueue, the signal handler will still be invoked, so it's // important to replace it with our "benign" handler. int ret = sigaction(signo, &new_action, &info.old_action); + (void)ret; assert(ret == 0 && "sigaction failed"); #if HAVE_SYS_EVENT_H diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp index 90272cb8d0bc6..fd349cc2915b7 100644 --- a/source/Host/common/NativeProcessProtocol.cpp +++ b/source/Host/common/NativeProcessProtocol.cpp @@ -16,6 +16,8 @@ #include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" +#include "llvm/Support/Process.h" + using namespace lldb; using namespace lldb_private; @@ -329,22 +331,23 @@ void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged( if (log) { if (!m_delegates.empty()) { - log->Printf("NativeProcessProtocol::%s: sent state notification [%s] " - "from process %" PRIu64, - __FUNCTION__, lldb_private::StateAsCString(state), GetID()); + LLDB_LOGF(log, + "NativeProcessProtocol::%s: sent state notification [%s] " + "from process %" PRIu64, + __FUNCTION__, lldb_private::StateAsCString(state), GetID()); } else { - log->Printf("NativeProcessProtocol::%s: would send state notification " - "[%s] from process %" PRIu64 ", but no delegates", - __FUNCTION__, lldb_private::StateAsCString(state), GetID()); + LLDB_LOGF(log, + "NativeProcessProtocol::%s: would send state notification " + "[%s] from process %" PRIu64 ", but no delegates", + __FUNCTION__, lldb_private::StateAsCString(state), GetID()); } } } void NativeProcessProtocol::NotifyDidExec() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); - if (log) - log->Printf("NativeProcessProtocol::%s - preparing to call delegates", - __FUNCTION__); + LLDB_LOGF(log, "NativeProcessProtocol::%s - preparing to call delegates", + __FUNCTION__); { std::lock_guard<std::recursive_mutex> guard(m_delegates_mutex); @@ -524,6 +527,7 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { switch (GetArchitecture().GetMachine()) { case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: return llvm::makeArrayRef(g_aarch64_opcode); case llvm::Triple::x86: @@ -560,6 +564,7 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { case llvm::Triple::arm: case llvm::Triple::aarch64: + case llvm::Triple::aarch64_32: case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::mips: @@ -659,6 +664,58 @@ Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr, return Status(); } +llvm::Expected<llvm::StringRef> +NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer, + size_t max_size, + size_t &total_bytes_read) { + static const size_t cache_line_size = + llvm::sys::Process::getPageSizeEstimate(); + size_t bytes_read = 0; + size_t bytes_left = max_size; + addr_t curr_addr = addr; + size_t string_size; + char *curr_buffer = buffer; + total_bytes_read = 0; + Status status; + + while (bytes_left > 0 && status.Success()) { + addr_t cache_line_bytes_left = + cache_line_size - (curr_addr % cache_line_size); + addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left); + status = ReadMemory(curr_addr, reinterpret_cast<void *>(curr_buffer), + bytes_to_read, bytes_read); + + if (bytes_read == 0) + break; + + void *str_end = std::memchr(curr_buffer, '\0', bytes_read); + if (str_end != nullptr) { + total_bytes_read = + (size_t)(reinterpret_cast<char *>(str_end) - buffer + 1); + status.Clear(); + break; + } + + total_bytes_read += bytes_read; + curr_buffer += bytes_read; + curr_addr += bytes_read; + bytes_left -= bytes_read; + } + + string_size = total_bytes_read - 1; + + // Make sure we return a null terminated string. + if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') { + buffer[max_size - 1] = '\0'; + total_bytes_read--; + } + + if (!status.Success()) + return status.ToError(); + + return llvm::StringRef(buffer, string_size); +} + lldb::StateType NativeProcessProtocol::GetState() const { std::lock_guard<std::recursive_mutex> guard(m_state_mutex); return m_state; diff --git a/source/Host/common/NativeRegisterContext.cpp b/source/Host/common/NativeRegisterContext.cpp index 2f30d52aea639..fe40073eb59de 100644 --- a/source/Host/common/NativeRegisterContext.cpp +++ b/source/Host/common/NativeRegisterContext.cpp @@ -114,16 +114,15 @@ lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) { uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - if (log) - log->Printf("NativeRegisterContext::%s using reg index %" PRIu32 - " (default %" PRIu64 ")", - __FUNCTION__, reg, fail_value); + LLDB_LOGF(log, + "NativeRegisterContext::%s using reg index %" PRIu32 + " (default %" PRIu64 ")", + __FUNCTION__, reg, fail_value); const uint64_t retval = ReadRegisterAsUnsigned(reg, fail_value); - if (log) - log->Printf("NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, - __FUNCTION__, retval); + LLDB_LOGF(log, "NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, + __FUNCTION__, retval); return retval; } @@ -192,20 +191,19 @@ NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info, RegisterValue value; Status error = ReadRegister(reg_info, value); if (error.Success()) { - if (log) - log->Printf("NativeRegisterContext::%s ReadRegister() succeeded, value " - "%" PRIu64, - __FUNCTION__, value.GetAsUInt64()); + LLDB_LOGF(log, + "NativeRegisterContext::%s ReadRegister() succeeded, value " + "%" PRIu64, + __FUNCTION__, value.GetAsUInt64()); return value.GetAsUInt64(); } else { - if (log) - log->Printf("NativeRegisterContext::%s ReadRegister() failed, error %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, + "NativeRegisterContext::%s ReadRegister() failed, error %s", + __FUNCTION__, error.AsCString()); } } else { - if (log) - log->Printf("NativeRegisterContext::%s ReadRegister() null reg_info", - __FUNCTION__); + LLDB_LOGF(log, "NativeRegisterContext::%s ReadRegister() null reg_info", + __FUNCTION__); } return fail_value; } diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp index a89f1178e96c1..6358ab8a8e774 100644 --- a/source/Host/common/Socket.cpp +++ b/source/Host/common/Socket.cpp @@ -74,9 +74,10 @@ bool IsInterrupted() { Socket::Socket(SocketProtocol protocol, bool should_close, bool child_processes_inherit) - : IOObject(eFDTypeSocket, should_close), m_protocol(protocol), + : IOObject(eFDTypeSocket), m_protocol(protocol), m_socket(kInvalidSocketValue), - m_child_processes_inherit(child_processes_inherit) {} + m_child_processes_inherit(child_processes_inherit), + m_should_close_fd(should_close) {} Socket::~Socket() { Close(); } @@ -114,16 +115,16 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, switch (protocol) { case ProtocolTcp: socket_up = - llvm::make_unique<TCPSocket>(true, child_processes_inherit); + std::make_unique<TCPSocket>(true, child_processes_inherit); break; case ProtocolUdp: socket_up = - llvm::make_unique<UDPSocket>(true, child_processes_inherit); + std::make_unique<UDPSocket>(true, child_processes_inherit); break; case ProtocolUnixDomain: #ifndef LLDB_DISABLE_POSIX socket_up = - llvm::make_unique<DomainSocket>(true, child_processes_inherit); + std::make_unique<DomainSocket>(true, child_processes_inherit); #else error.SetErrorString( "Unix domain sockets are not supported on this platform."); @@ -132,7 +133,7 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, case ProtocolUnixAbstract: #ifdef __linux__ socket_up = - llvm::make_unique<AbstractSocket>(child_processes_inherit); + std::make_unique<AbstractSocket>(child_processes_inherit); #else error.SetErrorString( "Abstract domain sockets are not supported on this platform."); @@ -149,9 +150,8 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol, Status Socket::TcpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); - if (log) - log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.str().c_str()); + LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, + host_and_port.str().c_str()); Status error; std::unique_ptr<Socket> connect_socket( @@ -170,8 +170,7 @@ Status Socket::TcpListen(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket, Predicate<uint16_t> *predicate, int backlog) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); + LLDB_LOGF(log, "Socket::%s (%s)", __FUNCTION__, host_and_port.str().c_str()); Status error; std::string host_str; @@ -209,9 +208,8 @@ Status Socket::TcpListen(llvm::StringRef host_and_port, Status Socket::UdpConnect(llvm::StringRef host_and_port, bool child_processes_inherit, Socket *&socket) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("Socket::%s (host/port = %s)", __FUNCTION__, - host_and_port.str().c_str()); + LLDB_LOGF(log, "Socket::%s (host/port = %s)", __FUNCTION__, + host_and_port.str().c_str()); return UDPSocket::Connect(host_and_port, child_processes_inherit, socket); } @@ -285,27 +283,25 @@ bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port, int32_t &port, Status *error_ptr) { static RegularExpression g_regex( llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)")); - RegularExpression::Match regex_match(2); - if (g_regex.Execute(host_and_port, ®ex_match)) { - if (regex_match.GetMatchAtIndex(host_and_port, 1, host_str) && - regex_match.GetMatchAtIndex(host_and_port, 2, port_str)) { - // IPv6 addresses are wrapped in [] when specified with ports - if (host_str.front() == '[' && host_str.back() == ']') - host_str = host_str.substr(1, host_str.size() - 2); - bool ok = false; - port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); - if (ok && port <= UINT16_MAX) { - if (error_ptr) - error_ptr->Clear(); - return true; - } - // port is too large + llvm::SmallVector<llvm::StringRef, 3> matches; + if (g_regex.Execute(host_and_port, &matches)) { + host_str = matches[1].str(); + port_str = matches[2].str(); + // IPv6 addresses are wrapped in [] when specified with ports + if (host_str.front() == '[' && host_str.back() == ']') + host_str = host_str.substr(1, host_str.size() - 2); + bool ok = false; + port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok); + if (ok && port <= UINT16_MAX) { if (error_ptr) - error_ptr->SetErrorStringWithFormat( - "invalid host:port specification: '%s'", - host_and_port.str().c_str()); - return false; + error_ptr->Clear(); + return true; } + // port is too large + if (error_ptr) + error_ptr->SetErrorStringWithFormat( + "invalid host:port specification: '%s'", host_and_port.str().c_str()); + return false; } // If this was unsuccessful, then check if it's simply a signed 32-bit @@ -345,18 +341,20 @@ Status Socket::Read(void *buf, size_t &num_bytes) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); if (log) { - log->Printf("%p Socket::Read() (socket = %" PRIu64 - ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 - " (error = %s)", - static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, - static_cast<uint64_t>(num_bytes), - static_cast<int64_t>(bytes_received), error.AsCString()); + LLDB_LOGF(log, + "%p Socket::Read() (socket = %" PRIu64 + ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 + " (error = %s)", + static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, + static_cast<uint64_t>(num_bytes), + static_cast<int64_t>(bytes_received), error.AsCString()); } return error; } Status Socket::Write(const void *buf, size_t &num_bytes) { + const size_t src_len = num_bytes; Status error; int bytes_sent = 0; do { @@ -371,12 +369,13 @@ Status Socket::Write(const void *buf, size_t &num_bytes) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); if (log) { - log->Printf("%p Socket::Write() (socket = %" PRIu64 - ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 - " (error = %s)", - static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, - static_cast<uint64_t>(num_bytes), - static_cast<int64_t>(bytes_sent), error.AsCString()); + LLDB_LOGF(log, + "%p Socket::Write() (socket = %" PRIu64 + ", src = %p, src_len = %" PRIu64 ", flags = 0) => %" PRIi64 + " (error = %s)", + static_cast<void *>(this), static_cast<uint64_t>(m_socket), buf, + static_cast<uint64_t>(src_len), + static_cast<int64_t>(bytes_sent), error.AsCString()); } return error; @@ -393,9 +392,8 @@ Status Socket::Close() { return error; Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("%p Socket::Close (fd = %" PRIu64 ")", - static_cast<void *>(this), static_cast<uint64_t>(m_socket)); + LLDB_LOGF(log, "%p Socket::Close (fd = %" PRIu64 ")", + static_cast<void *>(this), static_cast<uint64_t>(m_socket)); #if defined(_WIN32) bool success = !!closesocket(m_socket); @@ -479,11 +477,11 @@ NativeSocket Socket::AcceptSocket(NativeSocket sockfd, struct sockaddr *addr, if (!child_processes_inherit) { flags |= SOCK_CLOEXEC; } - NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept4, - sockfd, addr, addrlen, flags); + NativeSocket fd = llvm::sys::RetryAfterSignal( + static_cast<NativeSocket>(-1), ::accept4, sockfd, addr, addrlen, flags); #else - NativeSocket fd = llvm::sys::RetryAfterSignal(-1, ::accept, - sockfd, addr, addrlen); + NativeSocket fd = llvm::sys::RetryAfterSignal( + static_cast<NativeSocket>(-1), ::accept, sockfd, addr, addrlen); #endif if (fd == kInvalidSocketValue) SetLastError(error); diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp index 58f99f7832fe2..e84054f3f5817 100644 --- a/source/Host/common/TCPSocket.cpp +++ b/source/Host/common/TCPSocket.cpp @@ -140,8 +140,7 @@ Status TCPSocket::CreateSocket(int domain) { Status TCPSocket::Connect(llvm::StringRef name) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION)); - if (log) - log->Printf("TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); + LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); Status error; std::string host_str; @@ -177,8 +176,7 @@ Status TCPSocket::Connect(llvm::StringRef name) { Status TCPSocket::Listen(llvm::StringRef name, int backlog) { Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data()); + LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data()); Status error; std::string host_str; diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp index 8dbf57d6fe4ec..7accbb651ba9b 100644 --- a/source/Host/common/UDPSocket.cpp +++ b/source/Host/common/UDPSocket.cpp @@ -58,8 +58,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, std::unique_ptr<UDPSocket> final_socket; Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION)); - if (log) - log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); + LLDB_LOGF(log, "UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); Status error; std::string host_str; @@ -81,7 +80,7 @@ Status UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit, &service_info_list); if (err != 0) { error.SetErrorStringWithFormat( -#if defined(_MSC_VER) && defined(UNICODE) +#if defined(_WIN32) && defined(UNICODE) "getaddrinfo(%s, %s, &hints, &info) returned error %i (%S)", #else "getaddrinfo(%s, %s, &hints, &info) returned error %i (%s)", |