aboutsummaryrefslogtreecommitdiffstats
path: root/source/Host/common
diff options
context:
space:
mode:
Diffstat (limited to 'source/Host/common')
-rw-r--r--source/Host/common/Editline.cpp172
-rw-r--r--source/Host/common/File.cpp410
-rw-r--r--source/Host/common/FileCache.cpp38
-rw-r--r--source/Host/common/FileSystem.cpp33
-rw-r--r--source/Host/common/Host.cpp39
-rw-r--r--source/Host/common/HostInfoBase.cpp21
-rw-r--r--source/Host/common/HostNativeThreadBase.cpp3
-rw-r--r--source/Host/common/LZMA.cpp146
-rw-r--r--source/Host/common/MainLoop.cpp1
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp75
-rw-r--r--source/Host/common/NativeRegisterContext.cpp32
-rw-r--r--source/Host/common/Socket.cpp102
-rw-r--r--source/Host/common/TCPSocket.cpp6
-rw-r--r--source/Host/common/UDPSocket.cpp5
14 files changed, 667 insertions, 416 deletions
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index d3a70aeaa326..3e655244b107 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 c8c8d7a0d496..9dae24d766f6 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 4bd3efda7fb0..d9dcad992c33 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 d5ac05bd447c..2db5bff3207f 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 3ba9ab7f21f3..8e210c7e5fa5 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 130f0eb8ac8d..3765f36fc79a 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 a5f876a7232a..fe7d85acaf11 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 000000000000..02be8a09df66
--- /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 1ce09a84671c..6f774451c8a4 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 90272cb8d0bc..fd349cc2915b 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 2f30d52aea63..fe40073eb59d 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 a89f1178e96c..6358ab8a8e77 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, &regex_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 58f99f7832fe..e84054f3f581 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 8dbf57d6fe4e..7accbb651ba9 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)",