diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:27:41 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:27:41 +0000 |
commit | 7e05710080279abf7913a446bf4d5bf6725ea82e (patch) | |
tree | 058ad14c97f537c7676c823024dad158fd6360d5 /gnu/llvm | |
parent | 4dddffde48564a9d86bc615415a839fe32f5794f (diff) |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm')
15 files changed, 698 insertions, 650 deletions
diff --git a/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp b/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp index 200008dcff5..6002efe9244 100644 --- a/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp +++ b/gnu/llvm/tools/lldb/source/Core/FormatEntity.cpp @@ -10,28 +10,29 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" +#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/ArchSpec.h" // for ArchSpec #include "lldb/Core/Debugger.h" -#include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/Module.h" +#include "lldb/Core/RegisterValue.h" // for RegisterValue #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/FormatClasses.h" +#include "lldb/DataFormatters/FormatClasses.h" // for TypeNameSpecifier... #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/DataFormatters/TypeSummary.h" +#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryImpl::... #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/CompilerType.h" // for CompilerType #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolContext.h" // for SymbolContext #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextS... #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -41,32 +42,30 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/ConstString.h" // for ConstString, oper... #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" -#include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/SharingPtr.h" +#include "lldb/Utility/Log.h" // for Log +#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego... +#include "lldb/Utility/SharingPtr.h" // for SharingPtr #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringList.h" -#include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-defines.h" -#include "lldb/lldb-forward.h" +#include "lldb/Utility/StringList.h" // for StringList +#include "lldb/Utility/StructuredData.h" // for StructuredData::O... +#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-forward.h" // for ValueObjectSP #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/Compiler.h" - -#include <ctype.h> -#include <inttypes.h> -#include <memory> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <type_traits> -#include <utility> +#include "llvm/ADT/Triple.h" // for Triple, Triple::O... +#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH + +#include <ctype.h> // for isxdigit +#include <inttypes.h> // for PRIu64, PRIx64 +#include <memory> // for shared_ptr, opera... +#include <stdio.h> // for sprintf +#include <stdlib.h> // for strtoul +#include <string.h> // for size_t, strchr +#include <type_traits> // for move +#include <utility> // for pair namespace lldb_private { class ScriptInterpreter; @@ -128,7 +127,6 @@ static FormatEntity::Entry::Definition g_frame_child_entries[] = { ENTRY("flags", FrameRegisterFlags, UInt64), ENTRY("no-debug", FrameNoDebug, None), ENTRY_CHILDREN("reg", FrameRegisterByName, UInt64, g_string_entry), - ENTRY("is-artificial", FrameIsArtificial, UInt32), }; static FormatEntity::Entry::Definition g_function_child_entries[] = { @@ -147,7 +145,6 @@ static FormatEntity::Entry::Definition g_function_child_entries[] = { static FormatEntity::Entry::Definition g_line_child_entries[] = { ENTRY_CHILDREN("file", LineEntryFile, None, g_file_child_entries), ENTRY("number", LineEntryLineNumber, UInt32), - ENTRY("column", LineEntryColumn, UInt32), ENTRY("start-addr", LineEntryStartAddress, UInt64), ENTRY("end-addr", LineEntryEndAddress, UInt64), }; @@ -358,7 +355,6 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(FrameRegisterFP); ENUM_TO_CSTR(FrameRegisterFlags); ENUM_TO_CSTR(FrameRegisterByName); - ENUM_TO_CSTR(FrameIsArtificial); ENUM_TO_CSTR(ScriptFrame); ENUM_TO_CSTR(FunctionID); ENUM_TO_CSTR(FunctionDidChange); @@ -375,7 +371,6 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(FunctionIsOptimized); ENUM_TO_CSTR(LineEntryFile); ENUM_TO_CSTR(LineEntryLineNumber); - ENUM_TO_CSTR(LineEntryColumn); ENUM_TO_CSTR(LineEntryStartAddress); ENUM_TO_CSTR(LineEntryEndAddress); ENUM_TO_CSTR(CurrentPCArrow); @@ -472,9 +467,10 @@ static bool DumpAddressOffsetFromFunction(Stream &s, const SymbolContext *sc, if (sc->function) { func_addr = sc->function->GetAddressRange().GetBaseAddress(); if (sc->block && !concrete_only) { - // Check to make sure we aren't in an inline function. If we are, use - // the inline block range that contains "format_addr" since blocks - // can be discontiguous. + // Check to make sure we aren't in an inline + // function. If we are, use the inline block + // range that contains "format_addr" since + // blocks can be discontiguous. Block *inline_block = sc->block->GetContainingInlinedBlock(); AddressRange inline_range; if (inline_block && @@ -626,7 +622,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, if (reg_info) { RegisterValue reg_value; if (reg_ctx->ReadRegister(reg_info, reg_value)) { - DumpRegisterValue(reg_value, &s, reg_info, false, false, format); + reg_value.Dump(&s, reg_info, false, false, format); return true; } } @@ -826,7 +822,8 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, if (do_deref_pointer && !is_array_range) { // I have not deref-ed yet, let's do it // this happens when we are not going through - // GetValueForVariableExpressionPath to get to the target ValueObject + // GetValueForVariableExpressionPath + // to get to the target ValueObject Status error; target = target->Dereference(error).get(); if (error.Fail()) { @@ -845,9 +842,9 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, return false; } - // we do not want to use the summary for a bitfield of type T:n if we were - // originally dealing with just a T - that would get us into an endless - // recursion + // we do not want to use the summary for a bitfield of type T:n + // if we were originally dealing with just a T - that would get + // us into an endless recursion if (target->IsBitfield() && was_var_indexed) { // TODO: check for a (T:n)-specific summary - we should still obey that StreamString bitfield_name; @@ -908,7 +905,8 @@ static bool DumpValue(Stream &s, const SymbolContext *sc, } // if directly trying to print ${var}, and this is an aggregate, display a - // nice type @ location message + // nice + // type @ location message if (is_aggregate && was_plain_var) { s << target->GetTypeName() << " @ " << target->GetLocationAsCString(); return true; @@ -1023,7 +1021,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name, if (reg_info) { RegisterValue reg_value; if (reg_ctx->ReadRegister(reg_info, reg_value)) { - DumpRegisterValue(reg_value, &s, reg_info, false, false, format); + reg_value.Dump(&s, reg_info, false, false, format); return true; } } @@ -1144,8 +1142,8 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (!success) break; } - // Only if all items in a scope succeed, then do we print the output into - // the main stream + // Only if all items in a scope succeed, then do we + // print the output into the main stream if (success) s.Write(scope_stream.GetString().data(), scope_stream.GetString().size()); } @@ -1208,8 +1206,9 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, // Watch for the special "tid" format... if (entry.printf_format == "tid") { // TODO(zturner): Rather than hardcoding this to be platform - // specific, it should be controlled by a setting and the default - // value of the setting can be different depending on the platform. + // specific, it should be controlled by a + // setting and the default value of the setting can be different + // depending on the platform. Target &target = thread->GetProcess()->GetTarget(); ArchSpec arch(target.GetArchitecture()); llvm::Triple::OSType ostype = arch.IsValid() @@ -1491,13 +1490,6 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, } return false; - case Entry::Type::FrameIsArtificial: { - if (exe_ctx) - if (StackFrame *frame = exe_ctx->GetFramePtr()) - return frame->IsArtificial(); - return false; - } - case Entry::Type::ScriptFrame: if (exe_ctx) { StackFrame *frame = exe_ctx->GetFramePtr(); @@ -1825,16 +1817,6 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, } return false; - case Entry::Type::LineEntryColumn: - if (sc && sc->line_entry.IsValid() && sc->line_entry.column) { - const char *format = "%" PRIu32; - if (!entry.printf_format.empty()) - format = entry.printf_format.c_str(); - s.Printf(format, sc->line_entry.column); - return true; - } - return false; - case Entry::Type::LineEntryStartAddress: case Entry::Type::LineEntryEndAddress: if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) { @@ -1932,9 +1914,9 @@ static Status ParseEntry(const llvm::StringRef &format_str, error.SetErrorStringWithFormat("%s", error_strm.GetData()); } else if (sep_char == ':') { // Any value whose separator is a with a ':' means this value has a - // string argument that needs to be stored in the entry (like - // "${script.var:}"). In this case the string value is the empty - // string which is ok. + // string argument + // that needs to be stored in the entry (like "${script.var:}"). + // In this case the string value is the empty string which is ok. } else { error.SetErrorStringWithFormat("%s", "invalid entry definitions"); } @@ -1944,7 +1926,8 @@ static Status ParseEntry(const llvm::StringRef &format_str, error = ParseEntry(value, entry_def, entry); } else if (sep_char == ':') { // Any value whose separator is a with a ':' means this value has a - // string argument that needs to be stored in the entry (like + // string argument + // that needs to be stored in the entry (like // "${script.var:modulename.function}") entry.string = value.str(); } else { @@ -2082,17 +2065,17 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry, case '0': // 1 to 3 octal chars { - // Make a string that can hold onto the initial zero char, up to 3 - // octal digits, and a terminating NULL. + // Make a string that can hold onto the initial zero char, + // up to 3 octal digits, and a terminating NULL. char oct_str[5] = {0, 0, 0, 0, 0}; int i; for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i) oct_str[i] = format[i]; - // We don't want to consume the last octal character since the main - // for loop will do this for us, so we advance p by one less than i - // (even if i is zero) + // We don't want to consume the last octal character since + // the main for loop will do this for us, so we advance p by + // one less than i (even if i is zero) format = format.drop_front(i); unsigned long octal_value = ::strtoul(oct_str, nullptr, 8); if (octal_value <= UINT8_MAX) { @@ -2132,8 +2115,8 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry, break; default: - // Just desensitize any other character by just printing what came - // after the '\' + // Just desensitize any other character by just printing what + // came after the '\' parent_entry.AppendChar(desens_char); break; } @@ -2159,9 +2142,10 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry, if (!variable_format.empty()) { entry.printf_format = variable_format.str(); - // If the format contains a '%' we are going to assume this is a - // printf style format. So if you want to format your thread ID - // using "0x%llx" you can use: ${thread.id%0x%llx} + // If the format contains a '%' we are going to assume this is + // a printf style format. So if you want to format your thread ID + // using "0x%llx" you can use: + // ${thread.id%0x%llx} // // If there is no '%' in the format, then it is assumed to be a // LLDB format name, or one of the extended formats specified in @@ -2280,9 +2264,9 @@ Status FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry, return error; } } - // Check if this entry just wants to insert a constant string value - // into the parent_entry, if so, insert the string with AppendText, - // else append the entry to the parent_entry. + // Check if this entry just wants to insert a constant string + // value into the parent_entry, if so, insert the string with + // AppendText, else append the entry to the parent_entry. if (entry.type == Entry::Type::InsertString) parent_entry.AppendText(entry.string.c_str()); else @@ -2366,11 +2350,12 @@ static void AddMatches(const FormatEntity::Entry::Definition *def, } } -size_t FormatEntity::AutoComplete(CompletionRequest &request) { - llvm::StringRef str = request.GetCursorArgumentPrefix().str(); - - request.SetWordComplete(false); - str = str.drop_front(request.GetMatchStartPoint()); +size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point, + int max_return_elements, bool &word_complete, + StringList &matches) { + word_complete = false; + str = str.drop_front(match_start_point); + matches.Clear(); const size_t dollar_pos = str.rfind('$'); if (dollar_pos == llvm::StringRef::npos) @@ -2380,7 +2365,7 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { if (dollar_pos == str.size() - 1) { std::string match = str.str(); match.append("{"); - request.AddCompletion(match); + matches.AppendString(match); return 1; } @@ -2398,10 +2383,8 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { llvm::StringRef partial_variable(str.substr(dollar_pos + 2)); if (partial_variable.empty()) { // Suggest all top level entites as we are just past "${" - StringList new_matches; - AddMatches(&g_root, str, llvm::StringRef(), new_matches); - request.AddCompletions(new_matches); - return request.GetNumberOfMatches(); + AddMatches(&g_root, str, llvm::StringRef(), matches); + return matches.GetSize(); } // We have a partially specified variable, find it @@ -2417,23 +2400,19 @@ size_t FormatEntity::AutoComplete(CompletionRequest &request) { // Exact match if (n > 0) { // "${thread.info" <TAB> - request.AddCompletion(MakeMatch(str, ".")); + matches.AppendString(MakeMatch(str, ".")); } else { // "${thread.id" <TAB> - request.AddCompletion(MakeMatch(str, "}")); - request.SetWordComplete(true); + matches.AppendString(MakeMatch(str, "}")); + word_complete = true; } } else if (remainder.equals(".")) { // "${thread." <TAB> - StringList new_matches; - AddMatches(entry_def, str, llvm::StringRef(), new_matches); - request.AddCompletions(new_matches); + AddMatches(entry_def, str, llvm::StringRef(), matches); } else { // We have a partial match // "${thre" <TAB> - StringList new_matches; - AddMatches(entry_def, str, remainder, new_matches); - request.AddCompletions(new_matches); + AddMatches(entry_def, str, remainder, matches); } - return request.GetNumberOfMatches(); + return matches.GetSize(); } diff --git a/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp b/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp index 172cb06a581..def3e0359f0 100644 --- a/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp +++ b/gnu/llvm/tools/lldb/source/Host/common/SocketAddress.cpp @@ -21,6 +21,7 @@ #include <stddef.h> #include <stdio.h> +// C Includes #if !defined(_WIN32) #include <arpa/inet.h> #endif @@ -28,6 +29,9 @@ #include <assert.h> #include <string.h> +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Host/PosixApi.h" // WindowsXP needs an inet_ntop implementation diff --git a/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp b/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp index 8db0498d14b..0535256b9aa 100644 --- a/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp +++ b/gnu/llvm/tools/lldb/source/Host/openbsd/Host.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// C Includes #include <sys/types.h> #include <sys/signal.h> @@ -18,9 +19,15 @@ #include <stdio.h> +// C++ Includes +// Other libraries and framework includes +// Project includes +#include "lldb/Core/Module.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/CleanUp.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" @@ -38,17 +45,16 @@ extern char **environ; using namespace lldb; using namespace lldb_private; -Environment Host::GetEnvironment() { - Environment env; +size_t Host::GetEnvironment(StringList &env) { char *v; char **var = environ; for (; var != NULL && *var != NULL; ++var) { v = strchr(*var, (int)'-'); if (v == NULL) continue; - env.insert(v); + env.AppendString(v); } - return env; + return env.GetSize(); } static bool @@ -68,7 +74,7 @@ GetOpenBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, cstr = data.GetCStr(&offset); if (cstr) { - process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(cstr, false); if (!(match_info_ptr == NULL || NameMatches( diff --git a/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp b/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp index 866a9897ee4..da99fd70242 100644 --- a/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp +++ b/gnu/llvm/tools/lldb/source/Host/posix/PipePosix.cpp @@ -61,13 +61,12 @@ bool SetCloexecFlag(int fd) { std::chrono::time_point<std::chrono::steady_clock> Now() { return std::chrono::steady_clock::now(); } -} // namespace +} PipePosix::PipePosix() : m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {} -PipePosix::PipePosix(lldb::pipe_t read, lldb::pipe_t write) - : m_fds{read, write} {} +PipePosix::PipePosix(int read_fd, int write_fd) : m_fds{read_fd, write_fd} {} PipePosix::PipePosix(PipePosix &&pipe_posix) : PipeBase{std::move(pipe_posix)}, @@ -126,16 +125,20 @@ Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) { Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl<char> &name) { - llvm::SmallString<128> named_pipe_path; - llvm::SmallString<128> pipe_spec((prefix + ".%%%%%%").str()); - FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir(); - if (!tmpdir_file_spec) + llvm::SmallString<PATH_MAX> named_pipe_path; + llvm::SmallString<PATH_MAX> pipe_spec((prefix + ".%%%%%%").str()); + FileSpec tmpdir_file_spec; + tmpdir_file_spec.Clear(); + if (HostInfo::GetLLDBPath(ePathTypeLLDBTempSystemDir, tmpdir_file_spec)) { + tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str()); + } else { tmpdir_file_spec.AppendPathComponent("/tmp"); - tmpdir_file_spec.AppendPathComponent(pipe_spec); + tmpdir_file_spec.AppendPathComponent(pipe_spec.c_str()); + } // It's possible that another process creates the target path after we've - // verified it's available but before we create it, in which case we should - // try again. + // verified it's available but before we create it, in which case we + // should try again. Status error; do { llvm::sys::fs::createUniqueFile(tmpdir_file_spec.GetPath(), diff --git a/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt index f8ee7c64cbb..7a100588e00 100644 --- a/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt +++ b/gnu/llvm/tools/lldb/source/Initialization/CMakeLists.txt @@ -1,3 +1,7 @@ +if ( CMAKE_SYSTEM_NAME MATCHES "Darwin" ) + list(APPEND EXTRA_PLUGINS lldbPluginObjectFileMachO) +endif() + if ( CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|NetBSD" ) list(APPEND EXTRA_PLUGINS lldbPluginProcessPOSIX) endif() @@ -19,6 +23,8 @@ add_lldb_library(lldbInitialization lldbPluginInstructionMIPS64 lldbPluginObjectContainerBSDArchive lldbPluginObjectContainerMachOArchive + lldbPluginObjectFileELF + lldbPluginObjectFilePECOFF lldbPluginProcessGDBRemote ${EXTRA_PLUGINS} ${LLDB_SYSTEM_LIBS} diff --git a/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp b/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp index d1d55fcfde7..e76ba4122bb 100644 --- a/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/gnu/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -14,14 +14,18 @@ #include "Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h" #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h" #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h" +#include "Plugins/ObjectFile/ELF/ObjectFileELF.h" +#include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" -#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Timer.h" +#if defined(__APPLE__) +#include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" +#endif + #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" #endif @@ -31,19 +35,18 @@ #include "lldb/Host/windows/windows.h" #endif +#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/TargetSelect.h" #include <string> using namespace lldb_private; -using namespace lldb_private::repro; SystemInitializerCommon::SystemInitializerCommon() {} SystemInitializerCommon::~SystemInitializerCommon() {} -llvm::Error -SystemInitializerCommon::Initialize(const InitializerOptions &options) { +void SystemInitializerCommon::Initialize() { #if defined(_MSC_VER) const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG"); if (disable_crash_dialog_var && @@ -66,17 +69,8 @@ SystemInitializerCommon::Initialize(const InitializerOptions &options) { } #endif - ReproducerMode mode = ReproducerMode::Off; - if (options.reproducer_capture) - mode = ReproducerMode::Capture; - if (options.reproducer_replay) - mode = ReproducerMode::Replay; - - if (auto e = Reproducer::Initialize(mode, FileSpec(options.reproducer_path))) - return e; - - FileSystem::Initialize(); - Log::Initialize(); + llvm::EnablePrettyStackTrace(); + InitializeLog(); HostInfo::Initialize(); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); @@ -85,6 +79,8 @@ SystemInitializerCommon::Initialize(const InitializerOptions &options) { // Initialize plug-ins ObjectContainerBSDArchive::Initialize(); + ObjectFileELF::Initialize(); + ObjectFilePECOFF::Initialize(); EmulateInstructionARM::Initialize(); EmulateInstructionMIPS::Initialize(); @@ -95,26 +91,32 @@ SystemInitializerCommon::Initialize(const InitializerOptions &options) { //---------------------------------------------------------------------- ObjectContainerUniversalMachO::Initialize(); +#if defined(__APPLE__) + ObjectFileMachO::Initialize(); +#endif #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) ProcessPOSIXLog::Initialize(); #endif #if defined(_MSC_VER) ProcessWindowsLog::Initialize(); #endif - - return llvm::Error::success(); } void SystemInitializerCommon::Terminate() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); ObjectContainerBSDArchive::Terminate(); + ObjectFileELF::Terminate(); + ObjectFilePECOFF::Terminate(); EmulateInstructionARM::Terminate(); EmulateInstructionMIPS::Terminate(); EmulateInstructionMIPS64::Terminate(); ObjectContainerUniversalMachO::Terminate(); +#if defined(__APPLE__) + ObjectFileMachO::Terminate(); +#endif #if defined(_MSC_VER) ProcessWindowsLog::Terminate(); @@ -122,6 +124,4 @@ void SystemInitializerCommon::Terminate() { HostInfo::Terminate(); Log::DisableAllLogChannels(); - FileSystem::Terminate(); - Reproducer::Terminate(); } diff --git a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index b30a1ab2cf1..c1986976b0f 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -7,6 +7,10 @@ // //===----------------------------------------------------------------------===// +// C Includes +// C++ Includes +// Other libraries and framework includes +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/Symbol.h" @@ -14,7 +18,6 @@ #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" @@ -45,8 +48,8 @@ static addr_t ResolveRendezvousAddress(Process *process) { if (log) log->Printf("%s info_location = 0x%" PRIx64, __FUNCTION__, info_location); - // If the process fails to return an address, fall back to seeing if the - // local object file can help us find it. + // If the process fails to return an address, fall back to seeing if the local + // object file can help us find it. if (info_location == LLDB_INVALID_ADDRESS) { Target *target = &process->GetTarget(); if (target) { @@ -190,8 +193,8 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) { if (!fromRemote && m_current.map_addr == 0) return false; - // When the previous and current states are consistent this is the first time - // we have been asked to update. Just take a snapshot of the currently + // When the previous and current states are consistent this is the first + // time we have been asked to update. Just take a snapshot of the currently // loaded modules. if (m_previous.state == eConsistent && m_current.state == eConsistent) return fromRemote ? SaveSOEntriesFromRemote(module_list) @@ -200,9 +203,9 @@ bool DYLDRendezvous::UpdateSOEntries(bool fromRemote) { // If we are about to add or remove a shared object clear out the current // state and take a snapshot of the currently loaded images. if (m_current.state == eAdd || m_current.state == eDelete) { - // Some versions of the android dynamic linker might send two notifications - // with state == eAdd back to back. Ignore them until we get an eConsistent - // notification. + // Some versions of the android dynamic linker might send two + // notifications with state == eAdd back to back. Ignore them + // until we get an eConsistent notification. if (!(m_previous.state == eConsistent || (m_previous.state == eAdd && m_current.state == eDelete))) return false; @@ -243,7 +246,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo( entry.base_addr = base_addr; entry.dyn_addr = dyn_addr; - entry.file_spec.SetFile(name, FileSpec::Style::native); + entry.file_spec.SetFile(name, false); UpdateBaseAddrIfNecessary(entry, name); @@ -449,22 +452,30 @@ std::string DYLDRendezvous::ReadStringFromMemory(addr_t addr) { } // Returns true if the load bias reported by the linker is incorrect for the -// given entry. This function is used to handle cases where we want to work -// around a bug in the system linker. +// given entry. This +// function is used to handle cases where we want to work around a bug in the +// system linker. static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) { // On Android L (API 21, 22) the load address of the "/system/bin/linker" - // isn't filled in correctly. - unsigned os_major = target.GetPlatform()->GetOSVersion().getMajor(); - return target.GetArchitecture().GetTriple().isAndroid() && - (os_major == 21 || os_major == 22) && - (file_path == "/system/bin/linker" || - file_path == "/system/bin/linker64"); + // isn't filled in + // correctly. + uint32_t os_major = 0, os_minor = 0, os_update = 0; + if (target.GetArchitecture().GetTriple().isAndroid() && + target.GetPlatform()->GetOSVersion(os_major, os_minor, os_update) && + (os_major == 21 || os_major == 22) && + (file_path == "/system/bin/linker" || + file_path == "/system/bin/linker64")) { + return true; + } + + return false; } void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, std::string const &file_path) { // If the load bias reported by the linker is incorrect then fetch the load - // address of the file from the proc file system. + // address of the file + // from the proc file system. if (isLoadBiasIncorrect(m_process->GetTarget(), file_path)) { lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; bool is_loaded = false; @@ -483,8 +494,8 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { if (!(addr = ReadPointer(addr, &entry.base_addr))) return false; - // mips adds an extra load offset field to the link map struct on FreeBSD and - // NetBSD (need to validate other OSes). + // mips adds an extra load offset field to the link map struct on + // FreeBSD and NetBSD (need to validate other OSes). // http://svnweb.freebsd.org/base/head/sys/sys/link_elf.h?revision=217153&view=markup#l57 const ArchSpec &arch = m_process->GetTarget().GetArchitecture(); if ((arch.GetTriple().getOS() == llvm::Triple::FreeBSD || @@ -513,7 +524,7 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { return false; std::string file_path = ReadStringFromMemory(entry.path_addr); - entry.file_spec.SetFile(file_path, FileSpec::Style::native); + entry.file_spec.SetFile(file_path, false); UpdateBaseAddrIfNecessary(entry, file_path); diff --git a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 6774b4fd129..a7afeb6d68c 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -10,8 +10,10 @@ // Main header include #include "DynamicLoaderPOSIXDYLD.h" +// Project includes #include "AuxVector.h" +// Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -27,6 +29,8 @@ #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Utility/Log.h" +// C++ Includes +// C Includes using namespace lldb; using namespace lldb_private; @@ -75,8 +79,7 @@ DynamicLoaderPOSIXDYLD::DynamicLoaderPOSIXDYLD(Process *process) : DynamicLoader(process), m_rendezvous(process), m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS), m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID), - m_vdso_base(LLDB_INVALID_ADDRESS), - m_interpreter_base(LLDB_INVALID_ADDRESS) {} + m_vdso_base(LLDB_INVALID_ADDRESS) {} DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() { if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { @@ -114,10 +117,10 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { : "<null executable>", load_offset); - EvalSpecialModulesStatus(); + EvalVdsoStatus(); // if we dont have a load address we cant re-base - bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS; + bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true; // if we have a valid executable if (executable_sp.get()) { @@ -149,10 +152,31 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { UpdateLoadedSections(executable_sp, LLDB_INVALID_ADDRESS, load_offset, true); - LoadAllCurrentModules(); - if (!SetRendezvousBreakpoint()) { - // If we cannot establish rendezvous breakpoint right now we'll try again - // at entry point. + // When attaching to a target, there are two possible states: + // (1) We already crossed the entry point and therefore the rendezvous + // structure is ready to be used and we can load the list of modules + // and place the rendezvous breakpoint. + // (2) We didn't cross the entry point yet, so these structures are not + // ready; we should behave as if we just launched the target and + // call ProbeEntry(). This will place a breakpoint on the entry + // point which itself will be hit after the rendezvous structure is + // set up and will perform actions described in (1). + if (m_rendezvous.Resolve()) { + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 + " rendezvous could resolve: attach assuming dynamic loader " + "info is available now", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); + LoadAllCurrentModules(); + SetRendezvousBreakpoint(); + } else { + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s() pid %" PRIu64 + " rendezvous could not yet resolve: adding breakpoint to " + "catch future rendezvous setup", + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); ProbeEntry(); } @@ -183,7 +207,7 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() { executable = GetTargetExecutable(); load_offset = ComputeLoadOffset(); - EvalSpecialModulesStatus(); + EvalVdsoStatus(); if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) { ModuleList module_list; @@ -193,14 +217,8 @@ void DynamicLoaderPOSIXDYLD::DidLaunch() { if (log) log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()", __FUNCTION__); + ProbeEntry(); - if (!SetRendezvousBreakpoint()) { - // If we cannot establish rendezvous breakpoint right now we'll try again - // at entry point. - ProbeEntry(); - } - - LoadVDSO(); m_process->GetTarget().ModulesDidLoad(module_list); } } @@ -255,11 +273,11 @@ void DynamicLoaderPOSIXDYLD::ProbeEntry() { } // The runtime linker has run and initialized the rendezvous structure once the -// process has hit its entry point. When we hit the corresponding breakpoint -// we interrogate the rendezvous structure to get the load addresses of all +// process has hit its entry point. When we hit the corresponding breakpoint we +// interrogate the rendezvous structure to get the load addresses of all // dependent modules for the process. Similarly, we can discover the runtime -// linker function and setup a breakpoint to notify us of any dynamically -// loaded modules (via dlopen). +// linker function and setup a breakpoint to notify us of any dynamically loaded +// modules (via dlopen). bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( void *baton, StoppointCallbackContext *context, user_id_t break_id, user_id_t break_loc_id) { @@ -277,11 +295,13 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( : LLDB_INVALID_PROCESS_ID); // Disable the breakpoint --- if a stop happens right after this, which we've - // seen on occasion, we don't want the breakpoint stepping thread-plan logic - // to show a breakpoint instruction at the disassembled entry point to the - // program. Disabling it prevents it. (One-shot is not enough - one-shot - // removal logic only happens after the breakpoint goes public, which wasn't - // happening in our scenario). + // seen on occasion, we don't + // want the breakpoint stepping thread-plan logic to show a breakpoint + // instruction at the disassembled + // entry point to the program. Disabling it prevents it. (One-shot is not + // enough - one-shot removal logic + // only happens after the breakpoint goes public, which wasn't happening in + // our scenario). if (dyld_instance->m_process) { BreakpointSP breakpoint_sp = dyld_instance->m_process->GetTarget().GetBreakpointByID(break_id); @@ -309,77 +329,38 @@ bool DynamicLoaderPOSIXDYLD::EntryBreakpointHit( return false; // Continue running. } -bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { +void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - if (m_dyld_bid != LLDB_INVALID_BREAK_ID) { - LLDB_LOG(log, - "Rendezvous breakpoint breakpoint id {0} for pid {1}" - "is already set.", - m_dyld_bid, - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - return true; - } - addr_t break_addr; + addr_t break_addr = m_rendezvous.GetBreakAddress(); Target &target = m_process->GetTarget(); - BreakpointSP dyld_break; - if (m_rendezvous.IsValid()) { - break_addr = m_rendezvous.GetBreakAddress(); - LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}", - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, - break_addr); - dyld_break = target.CreateBreakpoint(break_addr, true, false); - } else { - LLDB_LOG(log, "Rendezvous structure is not set up yet. " - "Trying to locate rendezvous breakpoint in the interpreter " - "by symbol name."); - ModuleSP interpreter = LoadInterpreterModule(); - if (!interpreter) { - LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set."); - return false; - } - - // Function names from different dynamic loaders that are known to be used - // as rendezvous between the loader and debuggers. - static std::vector<std::string> DebugStateCandidates{ - "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity", - "r_debug_state", "_r_debug_state", "_rtld_debug_state", - }; - - FileSpecList containingModules; - containingModules.Append(interpreter->GetFileSpec()); - dyld_break = target.CreateBreakpoint( - &containingModules, nullptr /* containingSourceFiles */, - DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC, - 0, /* offset */ - eLazyBoolNo, /* skip_prologue */ - true, /* internal */ - false /* request_hardware */); - } - - if (dyld_break->GetNumResolvedLocations() != 1) { - LLDB_LOG( - log, - "Rendezvous breakpoint has abnormal number of" - " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.", - dyld_break->GetNumResolvedLocations(), - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - target.RemoveBreakpointByID(dyld_break->GetID()); - return false; + if (m_dyld_bid == LLDB_INVALID_BREAK_ID) { + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " setting rendezvous break address at 0x%" PRIx64, + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + break_addr); + Breakpoint *dyld_break = + target.CreateBreakpoint(break_addr, true, false).get(); + dyld_break->SetCallback(RendezvousBreakpointHit, this, true); + dyld_break->SetBreakpointKind("shared-library-event"); + m_dyld_bid = dyld_break->GetID(); + } else { + if (log) + log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64 + " reusing break id %" PRIu32 ", address at 0x%" PRIx64, + __FUNCTION__, + m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID, + m_dyld_bid, break_addr); } - BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0); - LLDB_LOG(log, - "Successfully set rendezvous breakpoint at address {0:x} " - "for pid {1}", - location->GetLoadAddress(), - m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID); - - dyld_break->SetCallback(RendezvousBreakpointHit, this, true); - dyld_break->SetBreakpointKind("shared-library-event"); - m_dyld_bid = dyld_break->GetID(); - return true; + // Make sure our breakpoint is at the right address. + assert(target.GetBreakpointByID(m_dyld_bid) + ->FindLocationByAddress(break_addr) + ->GetBreakpoint() + .GetID() == m_dyld_bid); } bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit( @@ -496,7 +477,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, AddressVector::iterator start = addrs.begin(); AddressVector::iterator end = addrs.end(); - llvm::sort(start, end); + std::sort(start, end); addrs.erase(std::unique(start, end), end); thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop)); } @@ -504,11 +485,11 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, return thread_plan_sp; } -void DynamicLoaderPOSIXDYLD::LoadVDSO() { +void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) { if (m_vdso_base == LLDB_INVALID_ADDRESS) return; - FileSpec file("[vdso]"); + FileSpec file("[vdso]", false); MemoryRegionInfo info; Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); @@ -525,40 +506,13 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() { } } -ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { - if (m_interpreter_base == LLDB_INVALID_ADDRESS) - return nullptr; - - MemoryRegionInfo info; - Target &target = m_process->GetTarget(); - Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info); - if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes || - info.GetName().IsEmpty()) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - LLDB_LOG(log, "Failed to get interpreter region info: {0}", status); - return nullptr; - } - - FileSpec file(info.GetName().GetCString()); - ModuleSpec module_spec(file, target.GetArchitecture()); - - if (ModuleSP module_sp = target.GetSharedModule(module_spec)) { - UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, - false); - return module_sp; - } - return nullptr; -} - void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { DYLDRendezvous::iterator I; DYLDRendezvous::iterator E; ModuleList module_list; - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - - LoadVDSO(); if (!m_rendezvous.Resolve()) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); if (log) log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD " "rendezvous address", @@ -566,10 +520,11 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { return; } - // The rendezvous class doesn't enumerate the main module, so track that - // ourselves here. + // The rendezvous class doesn't enumerate the main module, so track + // that ourselves here. ModuleSP executable = GetTargetExecutable(); m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress(); + LoadVDSO(module_list); std::vector<FileSpec> module_names; for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) @@ -581,8 +536,6 @@ void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() { ModuleSP module_sp = LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true); if (module_sp.get()) { - LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}", - I->file_spec.GetFilename()); module_list.Append(module_sp); } else { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); @@ -622,14 +575,11 @@ addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() { return m_load_offset; } -void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() { - auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR); - if (I != m_auxv->end() && I->value != 0) - m_vdso_base = I->value; +void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() { + AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR); - I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE); - if (I != m_auxv->end() && I->value != 0) - m_interpreter_base = I->value; + if (I != m_auxv->end()) + m_vdso_base = I->value; } addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() { @@ -752,7 +702,7 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( return; } - target.SetExecutableModule(module_sp, eLoadDependentsNo); + target.SetExecutableModule(module_sp, false); } bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo( diff --git a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 7358acb61f7..edb8ec951d3 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -10,24 +10,28 @@ #include "PlatformOpenBSD.h" #include "lldb/Host/Config.h" +// C Includes #include <stdio.h> #ifndef LLDB_DISABLE_POSIX #include <sys/utsname.h> #endif +// C++ Includes +// Other libraries and framework includes +// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" -// Define these constants from OpenBSD mman.h for use when targeting remote -// openbsd systems even when host has different values. +// Define these constants from OpenBSD mman.h for use when targeting +// remote openbsd systems even when host has different values. #define MAP_PRIVATE 0x0002 #define MAP_ANON 0x1000 @@ -46,7 +50,7 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { arch ? arch->GetTriple().getTriple() : "<null>"); bool create = force; - if (!create && arch && arch->IsValid()) { + if (create == false && arch && arch->IsValid()) { const llvm::Triple &triple = arch->GetTriple(); switch (triple.getOS()) { case llvm::Triple::OpenBSD: @@ -54,8 +58,9 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { break; #if defined(__OpenBSD__) - // Only accept "unknown" for the OS if the host is BSD and it "unknown" - // wasn't specified (it was just returned because it was NOT specified) + // Only accept "unknown" for the OS if the host is BSD and + // it "unknown" wasn't specified (it was just returned because it + // was NOT specified) case llvm::Triple::OSType::UnknownOS: create = !arch->TripleOSWasSpecified(); break; @@ -128,7 +133,7 @@ PlatformOpenBSD::PlatformOpenBSD(bool is_host) PlatformOpenBSD::~PlatformOpenBSD() = default; bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx, - ArchSpec &arch) { + ArchSpec &arch) { if (IsHost()) { ArchSpec hostArch = HostInfo::GetArchitecture(HostInfo::eArchKindDefault); if (hostArch.GetTriple().isOSOpenBSD()) { @@ -162,10 +167,13 @@ bool PlatformOpenBSD::GetSupportedArchitectureAtIndex(uint32_t idx, return false; } // Leave the vendor as "llvm::Triple:UnknownVendor" and don't specify the - // vendor by calling triple.SetVendorName("unknown") so that it is a - // "unspecified unknown". This means when someone calls - // triple.GetVendorName() it will return an empty string which indicates - // that the vendor can be set when two architectures are merged + // vendor by + // calling triple.SetVendorName("unknown") so that it is a "unspecified + // unknown". + // This means when someone calls triple.GetVendorName() it will return an + // empty string + // which indicates that the vendor can be set when two architectures are + // merged // Now set the triple into "arch" and return true arch.SetTriple(triple); @@ -203,17 +211,13 @@ void PlatformOpenBSD::CalculateTrapHandlerSymbolNames() { m_trap_handlers.push_back(ConstString("_sigtramp")); } -MmapArgList PlatformOpenBSD::GetMmapArgumentList(const ArchSpec &arch, - addr_t addr, addr_t length, - unsigned prot, unsigned flags, - addr_t fd, addr_t offset) { +uint64_t PlatformOpenBSD::ConvertMmapFlagsToPlatform(const ArchSpec &arch, + unsigned flags) { uint64_t flags_platform = 0; if (flags & eMmapFlagsPrivate) flags_platform |= MAP_PRIVATE; if (flags & eMmapFlagsAnon) flags_platform |= MAP_ANON; - - MmapArgList args({addr, length, prot, flags_platform, fd, offset}); - return args; + return flags_platform; } diff --git a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h index cb5e9bfe639..55f6451e236 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h +++ b/gnu/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.h @@ -53,10 +53,8 @@ public: void CalculateTrapHandlerSymbolNames() override; - MmapArgList GetMmapArgumentList(const ArchSpec &arch, lldb::addr_t addr, - lldb::addr_t length, unsigned prot, - unsigned flags, lldb::addr_t fd, - lldb::addr_t offset) override; + uint64_t ConvertMmapFlagsToPlatform(const ArchSpec &arch, + unsigned flags) override; private: DISALLOW_COPY_AND_ASSIGN(PlatformOpenBSD); diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt b/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt index fdeb211fe7a..62abd75a43b 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt +++ b/gnu/llvm/tools/lldb/source/Plugins/Process/CMakeLists.txt @@ -11,9 +11,9 @@ elseif (CMAKE_SYSTEM_NAME MATCHES "Windows") add_subdirectory(Windows/Common) elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin") add_subdirectory(MacOSX-Kernel) + add_subdirectory(mach-core) endif() add_subdirectory(gdb-remote) add_subdirectory(Utility) add_subdirectory(elf-core) -add_subdirectory(mach-core) add_subdirectory(minidump) diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index f11ef4f1bbf..f53db502be9 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -11,22 +11,24 @@ #include <errno.h> +// C Includes #ifdef __APPLE__ #include <TargetConditionals.h> #endif +// C++ Includes #include <chrono> #include <cstring> +// Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Config.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" -#include "lldb/Host/SafeMachO.h" -#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/Platform.h" @@ -38,8 +40,9 @@ #include "lldb/Utility/StreamString.h" #include "llvm/ADT/Triple.h" +// Project includes #include "ProcessGDBRemoteLog.h" -#include "lldb/Utility/StringExtractorGDBRemote.h" +#include "Utility/StringExtractorGDBRemote.h" #ifdef __ANDROID__ #include "lldb/Host/android/HostInfoAndroid.h" @@ -215,15 +218,12 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( if (sub != LLDB_INVALID_CPUTYPE) response.Printf("cpusubtype:%u;", sub); - if (cpu == llvm::MachO::CPU_TYPE_ARM - || cpu == llvm::MachO::CPU_TYPE_ARM64) { + if (cpu == ArchSpec::kCore_arm_any) { // Indicate the OS type. #if defined(TARGET_OS_TV) && TARGET_OS_TV == 1 response.PutCString("ostype:tvos;"); #elif defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1 response.PutCString("ostype:watchos;"); -#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1 - response.PutCString("ostype:bridgeos;"); #else response.PutCString("ostype:ios;"); #endif @@ -265,10 +265,19 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( break; } - llvm::VersionTuple version = HostInfo::GetOSVersion(); - if (!version.empty()) { - response.Format("os_version:{0}", version.getAsString()); - response.PutChar(';'); + uint32_t major = UINT32_MAX; + uint32_t minor = UINT32_MAX; + uint32_t update = UINT32_MAX; + if (HostInfo::GetOSVersion(major, minor, update)) { + if (major != UINT32_MAX) { + response.Printf("os_version:%u", major); + if (minor != UINT32_MAX) { + response.Printf(".%u", minor); + if (update != UINT32_MAX) + response.Printf(".%u", update); + } + response.PutChar(';'); + } } std::string s; @@ -286,9 +295,9 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( #if defined(__APPLE__) #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) - // For iOS devices, we are connected through a USB Mux so we never pretend to - // actually have a hostname as far as the remote lldb that is connecting to - // this lldb-platform is concerned + // For iOS devices, we are connected through a USB Mux so we never pretend + // to actually have a hostname as far as the remote lldb that is connecting + // to this lldb-platform is concerned response.PutCString("hostname:"); response.PutCStringAsRawHex8("127.0.0.1"); response.PutChar(';'); @@ -348,8 +357,7 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( StringExtractor extractor(value); std::string file; extractor.GetHexByteString(file); - match_info.GetProcessInfo().GetExecutableFile().SetFile( - file, FileSpec::Style::native); + match_info.GetProcessInfo().GetExecutableFile().SetFile(file, false); } else if (key.equals("name_match")) { NameMatch name_match = llvm::StringSwitch<NameMatch>(value) .Case("equals", NameMatch::Equals) @@ -393,10 +401,10 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( match_info.GetProcessInfo().SetEffectiveGroupID(gid); } else if (key.equals("all_users")) { match_info.SetMatchAllUsers( - OptionArgParser::ToBoolean(value, false, &success)); + Args::StringToBoolean(value, false, &success)); } else if (key.equals("triple")) { - match_info.GetProcessInfo().GetArchitecture() = - HostInfo::GetAugmentedArchSpec(value); + match_info.GetProcessInfo().GetArchitecture().SetTriple( + value.str().c_str(), NULL); } else { success = false; } @@ -407,8 +415,8 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( } if (Host::FindProcesses(match_info, m_proc_infos)) { - // We found something, return the first item by calling the get subsequent - // process info packet handler... + // We found something, return the first item by calling the get + // subsequent process info packet handler... return Handle_qsProcessInfo(packet); } return SendErrorResponse(3); @@ -516,8 +524,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); Status error; - FileSpec path_spec(path); - FileSystem::Instance().Resolve(path_spec); + const FileSpec path_spec{path, true}; int fd = ::open(path_spec.GetCString(), flags, mode); const int save_errno = fd == -1 ? errno : 0; StreamString response; @@ -656,14 +663,12 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - FileSpec file_spec(path); - FileSystem::Instance().Resolve(file_spec); - std::error_code ec; - const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); + Status error; + const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error); StreamString response; response.Printf("F%u", mode); - if (mode == 0 || ec) - response.Printf(",%i", (int)Status(ec).GetError()); + if (mode == 0 || error.Fail()) + response.Printf(",%i", (int)error.GetError()); return SendPacketNoLock(response.GetString()); } return SendErrorResponse(23); @@ -697,11 +702,7 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( packet.GetHexByteStringTerminatedBy(dst, ','); packet.GetChar(); // Skip ',' char packet.GetHexByteString(src); - - FileSpec src_spec(src); - FileSystem::Instance().Resolve(src_spec); - Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); - + Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false}); StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); @@ -730,15 +731,14 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( if (packet.GetChar() == ',') { // FIXME: add timeout to qPlatform_shell packet // uint32_t timeout = packet.GetHexMaxU32(false, 32); + uint32_t timeout = 10; if (packet.GetChar() == ',') packet.GetHexByteString(working_dir); int status, signo; std::string output; - FileSpec working_spec(working_dir); - FileSystem::Instance().Resolve(working_spec); Status err = - Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, - &output, std::chrono::seconds(10)); + Host::RunShellCommand(path.c_str(), FileSpec{working_dir, true}, + &status, &signo, &output, timeout); StreamGDBRemote response; if (err.Fail()) { response.PutCString("F,"); @@ -889,7 +889,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( packet.GetHexByteString(path); const bool read = true; const bool write = false; - if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { + if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -905,7 +905,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { + if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -921,7 +921,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { + if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -945,7 +945,8 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironment( packet.SetFilePos(::strlen("QEnvironment:")); const uint32_t bytes_left = packet.GetBytesLeft(); if (bytes_left > 0) { - m_process_launch_info.GetEnvironment().insert(packet.Peek()); + m_process_launch_info.GetEnvironmentEntries().AppendArgument( + llvm::StringRef::withNullAsEmpty(packet.Peek())); return SendOKResponse(); } return SendErrorResponse(12); @@ -959,7 +960,7 @@ GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded( if (bytes_left > 0) { std::string str; packet.GetHexByteString(str); - m_process_launch_info.GetEnvironment().insert(str); + m_process_launch_info.GetEnvironmentEntries().AppendArgument(str); return SendOKResponse(); } return SendErrorResponse(12); @@ -972,7 +973,8 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch( const uint32_t bytes_left = packet.GetBytesLeft(); if (bytes_left > 0) { const char *arch_triple = packet.Peek(); - m_process_launch_info.SetArchitecture(HostInfo::GetAugmentedArchSpec(arch_triple)); + ArchSpec arch_spec(arch_triple, NULL); + m_process_launch_info.SetArchitecture(arch_spec); return SendOKResponse(); } return SendErrorResponse(13); @@ -980,11 +982,11 @@ GDBRemoteCommunicationServerCommon::Handle_QLaunchArch( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { - // The 'A' packet is the most over designed packet ever here with redundant - // argument indexes, redundant argument lengths and needed hex encoded - // argument string values. Really all that is needed is a comma separated hex - // encoded argument value list, but we will stay true to the documented - // version of the 'A' packet here... + // The 'A' packet is the most over designed packet ever here with + // redundant argument indexes, redundant argument lengths and needed hex + // encoded argument string values. Really all that is needed is a comma + // separated hex encoded argument value list, but we will stay true to the + // documented version of the 'A' packet here... Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); int actual_arg_index = 0; @@ -992,8 +994,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { packet.SetFilePos(1); // Skip the 'A' bool success = true; while (success && packet.GetBytesLeft() > 0) { - // Decode the decimal argument string length. This length is the number of - // hex nibbles in the argument string value. + // Decode the decimal argument string length. This length is the + // number of hex nibbles in the argument string value. const uint32_t arg_len = packet.GetU32(UINT32_MAX); if (arg_len == UINT32_MAX) success = false; @@ -1002,8 +1004,8 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { if (packet.GetChar() != ',') success = false; else { - // Decode the argument index. We ignore this really because who would - // really send down the arguments in a random order??? + // Decode the argument index. We ignore this really because + // who would really send down the arguments in a random order??? const uint32_t arg_idx = packet.GetU32(UINT32_MAX); if (arg_idx == UINT32_MAX) success = false; @@ -1012,9 +1014,9 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { if (packet.GetChar() != ',') success = false; else { - // Decode the argument string value from hex bytes back into a UTF8 - // string and make sure the length matches the one supplied in the - // packet + // Decode the argument string value from hex bytes + // back into a UTF8 string and make sure the length + // matches the one supplied in the packet std::string arg; if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2)) @@ -1028,8 +1030,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { if (success) { if (arg_idx == 0) - m_process_launch_info.GetExecutableFile().SetFile( - arg, FileSpec::Style::native); + m_process_launch_info.GetExecutableFile().SetFile(arg, false); m_process_launch_info.GetArguments().AppendArgument(arg); if (log) log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"", @@ -1254,8 +1255,8 @@ void GDBRemoteCommunicationServerCommon:: // Nothing. break; } - // In case of MIPS64, pointer size is depend on ELF ABI For N32 the pointer - // size is 4 and for N64 it is 8 + // In case of MIPS64, pointer size is depend on ELF ABI + // For N32 the pointer size is 4 and for N64 it is 8 std::string abi = proc_arch.GetTargetABI(); if (!abi.empty()) response.Printf("elf_abi:%s;", abi.c_str()); @@ -1268,9 +1269,7 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); #else - FileSpec file_spec(module_path); - FileSystem::Instance().Resolve(file_spec); - return file_spec; + return FileSpec(module_path, true); #endif } @@ -1279,9 +1278,7 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - FileSpec req_module_path_spec(module_path); - FileSystem::Instance().Resolve(req_module_path_spec); - + const FileSpec req_module_path_spec(module_path, true); const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); const ModuleSpec module_spec(module_path_spec, arch); diff --git a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index cdb63e72f6b..9294359dbef 100644 --- a/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/gnu/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -14,10 +14,15 @@ #include "GDBRemoteCommunicationServerLLGS.h" #include "lldb/Utility/StreamGDBRemote.h" +// C Includes +// C++ Includes #include <chrono> #include <cstring> #include <thread> +// Other libraries and framework includes +#include "lldb/Core/RegisterValue.h" +#include "lldb/Core/State.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" #include "lldb/Host/File.h" @@ -28,24 +33,23 @@ #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" +#include "lldb/Interpreter/Args.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/MemoryRegionInfo.h" -#include "lldb/Utility/Args.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ScopedPrinter.h" +// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" -#include "lldb/Utility/StringExtractorGDBRemote.h" +#include "Utility/StringExtractorGDBRemote.h" using namespace lldb; using namespace lldb_private; @@ -200,8 +204,21 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() { }); } -void GDBRemoteCommunicationServerLLGS::SetLaunchInfo(const ProcessLaunchInfo &info) { - m_process_launch_info = info; +Status +GDBRemoteCommunicationServerLLGS::SetLaunchArguments(const char *const args[], + int argc) { + if ((argc < 1) || !args || !args[0] || !args[0][0]) + return Status("%s: no process command line specified to launch", + __FUNCTION__); + + m_process_launch_info.SetArguments(const_cast<const char **>(args), true); + return Status(); +} + +Status +GDBRemoteCommunicationServerLLGS::SetLaunchFlags(unsigned int launch_flags) { + m_process_launch_info.GetFlags().Set(launch_flags); + return Status(); } Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { @@ -218,10 +235,8 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { m_process_launch_info.SetLaunchInSeparateProcessGroup(true); m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); - if (should_forward_stdio) { - if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) - return Status(std::move(Err)); - } + const bool default_to_use_pty = true; + m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty); { std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); @@ -229,20 +244,26 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { "process but one already exists"); auto process_or = m_process_factory.Launch(m_process_launch_info, *this, m_mainloop); - if (!process_or) - return Status(process_or.takeError()); + if (!process_or) { + Status status(process_or.takeError()); + llvm::errs() << llvm::formatv( + "failed to launch executable `{0}`: {1}", + m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status); + return status; + } m_debugged_process_up = std::move(*process_or); } - // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol as - // needed. llgs local-process debugging may specify PTY paths, which will - // make these file actions non-null process launch -i/e/o will also make - // these file actions non-null nullptr means that the traffic is expected to - // flow over gdb-remote protocol + // Handle mirroring of inferior stdout/stderr over the gdb-remote protocol + // as needed. + // llgs local-process debugging may specify PTY paths, which will make these + // file actions non-null + // process launch -i/e/o will also make these file actions non-null + // nullptr means that the traffic is expected to flow over gdb-remote protocol if (should_forward_stdio) { // nullptr means it's not redirected to file or pty (in case of LLGS local) - // at least one of stdio will be transferred pty<->gdb-remote we need to - // give the pty master handle to this object to read and/or write + // at least one of stdio will be transferred pty<->gdb-remote + // we need to give the pty master handle to this object to read and/or write LLDB_LOG(log, "pid = {0}: setting up stdout/stderr redirection via $O " "gdb-remote commands", @@ -288,7 +309,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { // else. if (m_debugged_process_up && m_debugged_process_up->GetID() != LLDB_INVALID_PROCESS_ID) - return Status("cannot attach to process %" PRIu64 + return Status("cannot attach to a process %" PRIu64 " when another process with pid %" PRIu64 " is being debugged.", pid, m_debugged_process_up->GetID()); @@ -375,12 +396,12 @@ static void AppendHexValue(StreamString &response, const uint8_t *buf, } static void WriteRegisterValueInHexFixedWidth( - StreamString &response, NativeRegisterContext ®_ctx, + StreamString &response, NativeRegisterContextSP ®_ctx_sp, const RegisterInfo ®_info, const RegisterValue *reg_value_p, lldb::ByteOrder byte_order) { RegisterValue reg_value; if (!reg_value_p) { - Status error = reg_ctx.ReadRegister(®_info, reg_value); + Status error = reg_ctx_sp->ReadRegister(®_info, reg_value); if (error.Success()) reg_value_p = ®_value; // else log. @@ -402,13 +423,15 @@ static void WriteRegisterValueInHexFixedWidth( static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); - NativeRegisterContext& reg_ctx = thread.GetRegisterContext(); + NativeRegisterContextSP reg_ctx_sp = thread.GetRegisterContext(); + if (!reg_ctx_sp) + return nullptr; JSONObject::SP register_object_sp = std::make_shared<JSONObject>(); #ifdef LLDB_JTHREADSINFO_FULL_REGISTER_SET - // Expedite all registers in the first register set (i.e. should be GPRs) - // that are not contained in other registers. + // Expedite all registers in the first register set (i.e. should be GPRs) that + // are not contained in other registers. const RegisterSet *reg_set_p = reg_ctx_sp->GetRegisterSet(0); if (!reg_set_p) return nullptr; @@ -417,21 +440,22 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { uint32_t reg_num = *reg_num_p; #else // Expedite only a couple of registers until we figure out why sending - // registers is expensive. + // registers is + // expensive. static const uint32_t k_expedited_registers[] = { LLDB_REGNUM_GENERIC_PC, LLDB_REGNUM_GENERIC_SP, LLDB_REGNUM_GENERIC_FP, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM}; for (const uint32_t *generic_reg_p = k_expedited_registers; *generic_reg_p != LLDB_INVALID_REGNUM; ++generic_reg_p) { - uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber( + uint32_t reg_num = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( eRegisterKindGeneric, *generic_reg_p); if (reg_num == LLDB_INVALID_REGNUM) continue; // Target does not support the given register. #endif const RegisterInfo *const reg_info_p = - reg_ctx.GetRegisterInfoAtIndex(reg_num); + reg_ctx_sp->GetRegisterInfoAtIndex(reg_num); if (reg_info_p == nullptr) { if (log) log->Printf( @@ -445,7 +469,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { // registers. RegisterValue reg_value; - Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); + Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); if (error.Fail()) { if (log) log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", @@ -456,7 +480,7 @@ static JSONObject::SP GetRegistersAsJSON(NativeThreadProtocol &thread) { } StreamString stream; - WriteRegisterValueInHexFixedWidth(stream, reg_ctx, *reg_info_p, + WriteRegisterValueInHexFixedWidth(stream, reg_ctx_sp, *reg_info_p, ®_value, lldb::eByteOrderBig); register_object_sp->SetObject( @@ -499,16 +523,16 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, // Ensure we can get info on the given thread. uint32_t thread_idx = 0; - for (NativeThreadProtocol *thread; - (thread = process.GetThreadAtIndex(thread_idx)) != nullptr; + for (NativeThreadProtocolSP thread_sp; + (thread_sp = process.GetThreadAtIndex(thread_idx)) != nullptr; ++thread_idx) { - lldb::tid_t tid = thread->GetID(); + lldb::tid_t tid = thread_sp->GetID(); // Grab the reason this thread stopped. struct ThreadStopInfo tid_stop_info; std::string description; - if (!thread->GetStopReason(tid_stop_info, description)) + if (!thread_sp->GetStopReason(tid_stop_info, description)) return nullptr; const int signum = tid_stop_info.details.signal.signo; @@ -524,7 +548,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, threads_array_sp->AppendObject(thread_obj_sp); if (!abridged) { - if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread)) + if (JSONObject::SP registers_sp = GetRegistersAsJSON(*thread_sp)) thread_obj_sp->SetObject("registers", registers_sp); } @@ -532,7 +556,7 @@ static JSONArray::SP GetJSONThreadsInfo(NativeProcessProtocol &process, if (signum != 0) thread_obj_sp->SetObject("signal", std::make_shared<JSONNumber>(signum)); - const std::string thread_name = thread->GetName(); + const std::string thread_name = thread_sp->GetName(); if (!thread_name.empty()) thread_obj_sp->SetObject("name", std::make_shared<JSONString>(thread_name)); @@ -580,18 +604,19 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( m_debugged_process_up->GetID(), tid); // Ensure we can get info on the given thread. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); - if (!thread) + NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid)); + if (!thread_sp) return SendErrorResponse(51); // Grab the reason this thread stopped. struct ThreadStopInfo tid_stop_info; std::string description; - if (!thread->GetStopReason(tid_stop_info, description)) + if (!thread_sp->GetStopReason(tid_stop_info, description)) return SendErrorResponse(52); // FIXME implement register handling for exec'd inferiors. - // if (tid_stop_info.reason == eStopReasonExec) { + // if (tid_stop_info.reason == eStopReasonExec) + // { // const bool force = true; // InitializeRegisters(force); // } @@ -613,7 +638,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( response.Printf("thread:%" PRIx64 ";", tid); // Include the thread name if there is one. - const std::string thread_name = thread->GetName(); + const std::string thread_name = thread_sp->GetName(); if (!thread_name.empty()) { size_t thread_name_len = thread_name.length(); @@ -628,33 +653,36 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( response.PutChar(';'); } - // If a 'QListThreadsInStopReply' was sent to enable this feature, we will - // send all thread IDs back in the "threads" key whose value is a list of hex - // thread IDs separated by commas: + // If a 'QListThreadsInStopReply' was sent to enable this feature, we + // will send all thread IDs back in the "threads" key whose value is + // a list of hex thread IDs separated by commas: // "threads:10a,10b,10c;" - // This will save the debugger from having to send a pair of qfThreadInfo and - // qsThreadInfo packets, but it also might take a lot of room in the stop - // reply packet, so it must be enabled only on systems where there are no - // limits on packet lengths. + // This will save the debugger from having to send a pair of qfThreadInfo + // and qsThreadInfo packets, but it also might take a lot of room in the + // stop reply packet, so it must be enabled only on systems where there + // are no limits on packet lengths. if (m_list_threads_in_stop_reply) { response.PutCString("threads:"); uint32_t thread_index = 0; - NativeThreadProtocol *listed_thread; - for (listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index); - listed_thread; ++thread_index, - listed_thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) { + NativeThreadProtocolSP listed_thread_sp; + for (listed_thread_sp = + m_debugged_process_up->GetThreadAtIndex(thread_index); + listed_thread_sp; ++thread_index, + listed_thread_sp = m_debugged_process_up->GetThreadAtIndex( + thread_index)) { if (thread_index > 0) response.PutChar(','); - response.Printf("%" PRIx64, listed_thread->GetID()); + response.Printf("%" PRIx64, listed_thread_sp->GetID()); } response.PutChar(';'); - // Include JSON info that describes the stop reason for any threads that - // actually have stop reasons. We use the new "jstopinfo" key whose values - // is hex ascii JSON that contains the thread IDs thread stop info only for - // threads that have stop reasons. Only send this if we have more than one - // thread otherwise this packet has all the info it needs. + // Include JSON info that describes the stop reason for any threads + // that actually have stop reasons. We use the new "jstopinfo" key + // whose values is hex ascii JSON that contains the thread IDs + // thread stop info only for threads that have stop reasons. Only send + // this if we have more than one thread otherwise this packet has all + // the info it needs. if (thread_index > 0) { const bool threads_with_valid_stop_info_only = true; JSONArray::SP threads_info_sp = GetJSONThreadsInfo( @@ -673,18 +701,20 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( uint32_t i = 0; response.PutCString("thread-pcs"); char delimiter = ':'; - for (NativeThreadProtocol *thread; - (thread = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr; + for (NativeThreadProtocolSP thread_sp; + (thread_sp = m_debugged_process_up->GetThreadAtIndex(i)) != nullptr; ++i) { - NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); + NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (!reg_ctx_sp) + continue; - uint32_t reg_to_read = reg_ctx.ConvertRegisterKindToRegisterNumber( + uint32_t reg_to_read = reg_ctx_sp->ConvertRegisterKindToRegisterNumber( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); const RegisterInfo *const reg_info_p = - reg_ctx.GetRegisterInfoAtIndex(reg_to_read); + reg_ctx_sp->GetRegisterInfoAtIndex(reg_to_read); RegisterValue reg_value; - Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); + Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); if (error.Fail()) { if (log) log->Printf("%s failed to read register '%s' index %" PRIu32 ": %s", @@ -697,7 +727,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( response.PutChar(delimiter); delimiter = ','; - WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, + WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, ®_value, endian::InlHostByteOrder()); } @@ -709,48 +739,49 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( // // Grab the register context. - NativeRegisterContext& reg_ctx = thread->GetRegisterContext(); - // Expedite all registers in the first register set (i.e. should be GPRs) - // that are not contained in other registers. - const RegisterSet *reg_set_p; - if (reg_ctx.GetRegisterSetCount() > 0 && - ((reg_set_p = reg_ctx.GetRegisterSet(0)) != nullptr)) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers " - "from set '%s' (registers set count: %zu)", - __FUNCTION__, - reg_set_p->name ? reg_set_p->name : "<unnamed-set>", - reg_set_p->num_registers); - - for (const uint32_t *reg_num_p = reg_set_p->registers; - *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { - const RegisterInfo *const reg_info_p = - reg_ctx.GetRegisterInfoAtIndex(*reg_num_p); - if (reg_info_p == nullptr) { - if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get " - "register info for register set '%s', register index " - "%" PRIu32, - __FUNCTION__, - reg_set_p->name ? reg_set_p->name : "<unnamed-set>", - *reg_num_p); - } else if (reg_info_p->value_regs == nullptr) { - // Only expediate registers that are not contained in other registers. - RegisterValue reg_value; - Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); - if (error.Success()) { - response.Printf("%.02x:", *reg_num_p); - WriteRegisterValueInHexFixedWidth(response, reg_ctx, *reg_info_p, - ®_value, lldb::eByteOrderBig); - response.PutChar(';'); - } else { + NativeRegisterContextSP reg_ctx_sp = thread_sp->GetRegisterContext(); + if (reg_ctx_sp) { + // Expedite all registers in the first register set (i.e. should be GPRs) + // that are not contained in other registers. + const RegisterSet *reg_set_p; + if (reg_ctx_sp->GetRegisterSetCount() > 0 && + ((reg_set_p = reg_ctx_sp->GetRegisterSet(0)) != nullptr)) { + if (log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s expediting registers " + "from set '%s' (registers set count: %zu)", + __FUNCTION__, + reg_set_p->name ? reg_set_p->name : "<unnamed-set>", + reg_set_p->num_registers); + + for (const uint32_t *reg_num_p = reg_set_p->registers; + *reg_num_p != LLDB_INVALID_REGNUM; ++reg_num_p) { + const RegisterInfo *const reg_info_p = + reg_ctx_sp->GetRegisterInfoAtIndex(*reg_num_p); + if (reg_info_p == nullptr) { if (log) - log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read " - "register '%s' index %" PRIu32 ": %s", + log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to get " + "register info for register set '%s', register index " + "%" PRIu32, __FUNCTION__, - reg_info_p->name ? reg_info_p->name - : "<unnamed-register>", - *reg_num_p, error.AsCString()); + reg_set_p->name ? reg_set_p->name : "<unnamed-set>", + *reg_num_p); + } else if (reg_info_p->value_regs == nullptr) { + // Only expediate registers that are not contained in other registers. + RegisterValue reg_value; + Status error = reg_ctx_sp->ReadRegister(reg_info_p, reg_value); + if (error.Success()) { + response.Printf("%.02x:", *reg_num_p); + WriteRegisterValueInHexFixedWidth(response, reg_ctx_sp, *reg_info_p, + ®_value, lldb::eByteOrderBig); + response.PutChar(';'); + } else { + if (log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to read " + "register '%s' index %" PRIu32 ": %s", + __FUNCTION__, reg_info_p->name ? reg_info_p->name + : "<unnamed-register>", + *reg_num_p, error.AsCString()); + } } } } @@ -800,13 +831,12 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Exited( __FUNCTION__, process->GetID()); } - // Close the pipe to the inferior terminal i/o if we launched it and set one - // up. + // Close the pipe to the inferior terminal i/o if we launched it + // and set one up. MaybeCloseInferiorTerminalConnection(); // We are ready to exit the debug monitor. m_exit_now = true; - m_mainloop.RequestTermination(); } void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( @@ -817,7 +847,8 @@ void GDBRemoteCommunicationServerLLGS::HandleInferiorState_Stopped( if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s called", __FUNCTION__); - // Send the stop reason unless this is the stop after the launch or attach. + // Send the stop reason unless this is the stop after the + // launch or attach. switch (m_inferior_prev_state) { case eStateLaunching: case eStateAttaching: @@ -852,11 +883,13 @@ void GDBRemoteCommunicationServerLLGS::ProcessStateChanged( break; case StateType::eStateStopped: - // Make sure we get all of the pending stdout/stderr from the inferior and - // send it to the lldb host before we send the state change notification + // Make sure we get all of the pending stdout/stderr from the inferior + // and send it to the lldb host before we send the state change + // notification SendProcessOutput(); // Then stop the forwarding, so that any late output (see llvm.org/pr25652) - // does not interfere with our protocol. + // does not + // interfere with our protocol. StopSTDIOForwarding(); HandleInferiorState_Stopped(process); break; @@ -1278,17 +1311,17 @@ GDBRemoteCommunicationServerLLGS::Handle_qC(StringExtractorGDBRemote &packet) { (m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID)) return SendErrorResponse(68); - // Make sure we set the current thread so g and p packets return the data the - // gdb will expect. + // Make sure we set the current thread so g and p packets return + // the data the gdb will expect. lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID(); SetCurrentThreadID(tid); - NativeThreadProtocol *thread = m_debugged_process_up->GetCurrentThread(); - if (!thread) + NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetCurrentThread(); + if (!thread_sp) return SendErrorResponse(69); StreamString response; - response.Printf("QC%" PRIx64, thread->GetID()); + response.Printf("QC%" PRIx64, thread_sp->GetID()); return SendPacketNoLock(response.GetString()); } @@ -1331,7 +1364,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( packet.SetFilePos(::strlen("QSetWorkingDir:")); std::string path; packet.GetHexByteString(path); - m_process_launch_info.SetWorkingDirectory(FileSpec(path)); + m_process_launch_info.SetWorkingDirectory(FileSpec{path, true}); return SendOKResponse(); } @@ -1388,9 +1421,10 @@ GDBRemoteCommunicationServerLLGS::Handle_C(StringExtractorGDBRemote &packet) { Status error; // We have two branches: what to do if a continue thread is specified (in - // which case we target sending the signal to that thread), or when we don't - // have a continue thread set (in which case we send a signal to the - // process). + // which case we target + // sending the signal to that thread), or when we don't have a continue thread + // set (in which + // case we send a signal to the process). // TODO discuss with Greg Clayton, make sure this makes sense. @@ -1629,8 +1663,8 @@ GDBRemoteCommunicationServerLLGS::SendStopReasonForState( case eStateStopped: case eStateCrashed: { lldb::tid_t tid = m_debugged_process_up->GetCurrentThreadID(); - // Make sure we set the current thread so g and p packets return the data - // the gdb will expect. + // Make sure we set the current thread so g and p packets return + // the data the gdb will expect. SetCurrentThreadID(tid); return SendStopReplyPacketForThread(tid); } @@ -1658,12 +1692,14 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( return SendErrorResponse(68); // Ensure we have a thread. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadAtIndex(0); - if (!thread) + NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadAtIndex(0)); + if (!thread_sp) return SendErrorResponse(69); // Get the register context for the first thread. - NativeRegisterContext ®_context = thread->GetRegisterContext(); + NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); + if (!reg_context_sp) + return SendErrorResponse(69); // Parse out the register number from the request. packet.SetFilePos(strlen("qRegisterInfo")); @@ -1674,10 +1710,11 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( // Return the end of registers response if we've iterated one past the end of // the register set. - if (reg_index >= reg_context.GetUserRegisterCount()) + if (reg_index >= reg_context_sp->GetUserRegisterCount()) return SendErrorResponse(69); - const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); + const RegisterInfo *reg_info = + reg_context_sp->GetRegisterInfoAtIndex(reg_index); if (!reg_info) return SendErrorResponse(69); @@ -1759,7 +1796,7 @@ GDBRemoteCommunicationServerLLGS::Handle_qRegisterInfo( }; const char *const register_set_name = - reg_context.GetRegisterSetNameForRegisterAtIndex(reg_index); + reg_context_sp->GetRegisterSetNameForRegisterAtIndex(reg_index); if (register_set_name) { response.PutCString("set:"); response.PutCString(register_set_name); @@ -1871,17 +1908,18 @@ GDBRemoteCommunicationServerLLGS::Handle_qfThreadInfo( response.PutChar('m'); LLDB_LOG(log, "starting thread iteration"); - NativeThreadProtocol *thread; + NativeThreadProtocolSP thread_sp; uint32_t thread_index; for (thread_index = 0, - thread = m_debugged_process_up->GetThreadAtIndex(thread_index); - thread; ++thread_index, - thread = m_debugged_process_up->GetThreadAtIndex(thread_index)) { - LLDB_LOG(log, "iterated thread {0}(tid={2})", thread_index, - thread->GetID()); + thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index); + thread_sp; ++thread_index, + thread_sp = m_debugged_process_up->GetThreadAtIndex(thread_index)) { + LLDB_LOG(log, "iterated thread {0}({1}, tid={2})", thread_index, + thread_sp ? "is not null" : "null", + thread_sp ? thread_sp->GetID() : LLDB_INVALID_THREAD_ID); if (thread_index > 0) response.PutChar(','); - response.Printf("%" PRIx64, thread->GetID()); + response.Printf("%" PRIx64, thread_sp->GetID()); } LLDB_LOG(log, "finished thread iteration"); @@ -1913,27 +1951,38 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { } // Get the thread to use. - NativeThreadProtocol *thread = GetThreadFromSuffix(packet); - if (!thread) { - LLDB_LOG(log, "failed, no thread available"); + NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); + if (!thread_sp) { + if (log) + log->Printf( + "GDBRemoteCommunicationServerLLGS::%s failed, no thread available", + __FUNCTION__); return SendErrorResponse(0x15); } // Get the thread's register context. - NativeRegisterContext ®_context = thread->GetRegisterContext(); + NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); + if (!reg_context_sp) { + LLDB_LOG( + log, + "pid {0} tid {1} failed, no register context available for the thread", + m_debugged_process_up->GetID(), thread_sp->GetID()); + return SendErrorResponse(0x15); + } // Return the end of registers response if we've iterated one past the end of // the register set. - if (reg_index >= reg_context.GetUserRegisterCount()) { + if (reg_index >= reg_context_sp->GetUserRegisterCount()) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " "register %" PRIu32 " beyond register count %" PRIu32, __FUNCTION__, reg_index, - reg_context.GetUserRegisterCount()); + reg_context_sp->GetUserRegisterCount()); return SendErrorResponse(0x15); } - const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); + const RegisterInfo *reg_info = + reg_context_sp->GetRegisterInfoAtIndex(reg_index); if (!reg_info) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " @@ -1947,7 +1996,7 @@ GDBRemoteCommunicationServerLLGS::Handle_p(StringExtractorGDBRemote &packet) { // Retrieve the value RegisterValue reg_value; - Status error = reg_context.ReadRegister(reg_info, reg_value); + Status error = reg_context_sp->ReadRegister(reg_info, reg_value); if (error.Fail()) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, read of " @@ -1998,13 +2047,24 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { return SendIllFormedResponse( packet, "P packet missing '=' char after register number"); + // Get process architecture. + ArchSpec process_arch; + if (!m_debugged_process_up || + !m_debugged_process_up->GetArchitecture(process_arch)) { + if (log) + log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to retrieve " + "inferior architecture", + __FUNCTION__); + return SendErrorResponse(0x49); + } + // Parse out the value. uint8_t reg_bytes[32]; // big enough to support up to 256 bit ymmN register size_t reg_size = packet.GetHexBytesAvail(reg_bytes); // Get the thread to use. - NativeThreadProtocol *thread = GetThreadFromSuffix(packet); - if (!thread) { + NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); + if (!thread_sp) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, no thread " "available (thread index 0)", @@ -2013,8 +2073,18 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { } // Get the thread's register context. - NativeRegisterContext ®_context = thread->GetRegisterContext(); - const RegisterInfo *reg_info = reg_context.GetRegisterInfoAtIndex(reg_index); + NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); + if (!reg_context_sp) { + if (log) + log->Printf( + "GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64 " tid %" PRIu64 + " failed, no register context available for the thread", + __FUNCTION__, m_debugged_process_up->GetID(), thread_sp->GetID()); + return SendErrorResponse(0x15); + } + + const RegisterInfo *reg_info = + reg_context_sp->GetRegisterInfoAtIndex(reg_index); if (!reg_info) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " @@ -2025,16 +2095,18 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { // Return the end of registers response if we've iterated one past the end of // the register set. - if (reg_index >= reg_context.GetUserRegisterCount()) { + if (reg_index >= reg_context_sp->GetUserRegisterCount()) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, requested " "register %" PRIu32 " beyond register count %" PRIu32, - __FUNCTION__, reg_index, reg_context.GetUserRegisterCount()); + __FUNCTION__, reg_index, + reg_context_sp->GetUserRegisterCount()); return SendErrorResponse(0x47); } - // The dwarf expression are evaluate on host site which may cause register - // size to change Hence the reg_size may not be same as reg_info->bytes_size + // The dwarf expression are evaluate on host site + // which may cause register size to change + // Hence the reg_size may not be same as reg_info->bytes_size if ((reg_size != reg_info->byte_size) && !(reg_info->dynamic_size_dwarf_expr_bytes)) { return SendIllFormedResponse(packet, "P packet register size is incorrect"); @@ -2043,10 +2115,8 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { // Build the reginfos response. StreamGDBRemote response; - RegisterValue reg_value( - reg_bytes, reg_size, - m_debugged_process_up->GetArchitecture().GetByteOrder()); - Status error = reg_context.WriteRegister(reg_info, reg_value); + RegisterValue reg_value(reg_bytes, reg_size, process_arch.GetByteOrder()); + Status error = reg_context_sp->WriteRegister(reg_info, reg_value); if (error.Fail()) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, write of " @@ -2107,8 +2177,8 @@ GDBRemoteCommunicationServerLLGS::Handle_H(StringExtractorGDBRemote &packet) { // Ensure we have the given thread when not specifying -1 (all threads) or 0 // (any thread). if (tid != LLDB_INVALID_THREAD_ID && tid != 0) { - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); - if (!thread) { + NativeThreadProtocolSP thread_sp(m_debugged_process_up->GetThreadByID(tid)); + if (!thread_sp) { if (log) log->Printf("GDBRemoteCommunicationServerLLGS::%s failed, tid %" PRIu64 " not found", @@ -2365,9 +2435,10 @@ GDBRemoteCommunicationServerLLGS::Handle_qMemoryRegionInfoSupported( Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); // Currently only the NativeProcessProtocol knows if it can handle a - // qMemoryRegionInfoSupported request, but we're not guaranteed to be - // attached to a process. For now we'll assume the client only asks this - // when a process is being debugged. + // qMemoryRegionInfoSupported + // request, but we're not guaranteed to be attached to a process. For now + // we'll assume the + // client only asks this when a process is being debugged. // Ensure we have a process running; otherwise, we can't figure this out // since we won't have a NativeProcessProtocol. @@ -2658,7 +2729,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { } // We first try to use a continue thread id. If any one or any all set, use - // the current thread. Bail out if we don't have a thread id. + // the current thread. + // Bail out if we don't have a thread id. lldb::tid_t tid = GetContinueThreadID(); if (tid == 0 || tid == LLDB_INVALID_THREAD_ID) tid = GetCurrentThreadID(); @@ -2667,8 +2739,8 @@ GDBRemoteCommunicationServerLLGS::Handle_s(StringExtractorGDBRemote &packet) { // Double check that we have such a thread. // TODO investigate: on MacOSX we might need to do an UpdateThreads () here. - NativeThreadProtocol *thread = m_debugged_process_up->GetThreadByID(tid); - if (!thread) + NativeThreadProtocolSP thread_sp = m_debugged_process_up->GetThreadByID(tid); + if (!thread_sp || thread_sp->GetID() != tid) return SendErrorResponse(0x33); // Create the step action for the given thread. @@ -2793,8 +2865,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( packet.SetFilePos(strlen("QSaveRegisterState")); // Get the thread to use. - NativeThreadProtocol *thread = GetThreadFromSuffix(packet); - if (!thread) { + NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); + if (!thread_sp) { if (m_thread_suffix_supported) return SendIllFormedResponse( packet, "No thread specified in QSaveRegisterState packet"); @@ -2804,11 +2876,18 @@ GDBRemoteCommunicationServerLLGS::Handle_QSaveRegisterState( } // Grab the register context for the thread. - NativeRegisterContext& reg_context = thread->GetRegisterContext(); + NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); + if (!reg_context_sp) { + LLDB_LOG( + log, + "pid {0} tid {1} failed, no register context available for the thread", + m_debugged_process_up->GetID(), thread_sp->GetID()); + return SendErrorResponse(0x15); + } // Save registers to a buffer. DataBufferSP register_data_sp; - Status error = reg_context.ReadAllRegisterValues(register_data_sp); + Status error = reg_context_sp->ReadAllRegisterValues(register_data_sp); if (error.Fail()) { LLDB_LOG(log, "pid {0} failed to save all register values: {1}", m_debugged_process_up->GetID(), error); @@ -2851,8 +2930,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( } // Get the thread to use. - NativeThreadProtocol *thread = GetThreadFromSuffix(packet); - if (!thread) { + NativeThreadProtocolSP thread_sp = GetThreadFromSuffix(packet); + if (!thread_sp) { if (m_thread_suffix_supported) return SendIllFormedResponse( packet, "No thread specified in QRestoreRegisterState packet"); @@ -2862,7 +2941,14 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( } // Grab the register context for the thread. - NativeRegisterContext ®_context = thread->GetRegisterContext(); + NativeRegisterContextSP reg_context_sp(thread_sp->GetRegisterContext()); + if (!reg_context_sp) { + LLDB_LOG( + log, + "pid {0} tid {1} failed, no register context available for the thread", + m_debugged_process_up->GetID(), thread_sp->GetID()); + return SendErrorResponse(0x15); + } // Retrieve register state buffer, then remove from the list. DataBufferSP register_data_sp; @@ -2883,7 +2969,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QRestoreRegisterState( m_saved_registers_map.erase(it); } - Status error = reg_context.WriteAllRegisterValues(register_data_sp); + Status error = reg_context_sp->WriteAllRegisterValues(register_data_sp); if (error.Fail()) { LLDB_LOG(log, "pid {0} failed to restore all register values: {1}", m_debugged_process_up->GetID(), error); @@ -2922,7 +3008,7 @@ GDBRemoteCommunicationServerLLGS::Handle_vAttach( log->Printf("GDBRemoteCommunicationServerLLGS::%s failed to attach to " "pid %" PRIu64 ": %s\n", __FUNCTION__, pid, error.AsCString()); - return SendErrorResponse(error); + return SendErrorResponse(0x01); } // Notify we attached by sending a stop packet. @@ -3080,8 +3166,8 @@ GDBRemoteCommunicationServerLLGS::Handle_QPassSignals( std::vector<int> signals; packet.SetFilePos(strlen("QPassSignals:")); - // Read sequence of hex signal numbers divided by a semicolon and optionally - // spaces. + // Read sequence of hex signal numbers divided by a semicolon and + // optionally spaces. while (packet.GetBytesLeft() > 0) { int signal = packet.GetS32(-1, 16); if (signal < 0) @@ -3133,19 +3219,22 @@ void GDBRemoteCommunicationServerLLGS::MaybeCloseInferiorTerminalConnection() { } } -NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( +NativeThreadProtocolSP GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( StringExtractorGDBRemote &packet) { + NativeThreadProtocolSP thread_sp; + // We have no thread if we don't have a process. if (!m_debugged_process_up || m_debugged_process_up->GetID() == LLDB_INVALID_PROCESS_ID) - return nullptr; + return thread_sp; // If the client hasn't asked for thread suffix support, there will not be a - // thread suffix. Use the current thread in that case. + // thread suffix. + // Use the current thread in that case. if (!m_thread_suffix_supported) { const lldb::tid_t current_tid = GetCurrentThreadID(); if (current_tid == LLDB_INVALID_THREAD_ID) - return nullptr; + return thread_sp; else if (current_tid == 0) { // Pick a thread. return m_debugged_process_up->GetThreadAtIndex(0); @@ -3162,11 +3251,11 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( "error: expected ';' prior to start of thread suffix: packet " "contents = '%s'", __FUNCTION__, packet.GetStringRef().c_str()); - return nullptr; + return thread_sp; } if (!packet.GetBytesLeft()) - return nullptr; + return thread_sp; // Parse out thread: portion. if (strncmp(packet.Peek(), "thread:", strlen("thread:")) != 0) { @@ -3175,21 +3264,21 @@ NativeThreadProtocol *GDBRemoteCommunicationServerLLGS::GetThreadFromSuffix( "error: expected 'thread:' but not found, packet contents = " "'%s'", __FUNCTION__, packet.GetStringRef().c_str()); - return nullptr; + return thread_sp; } packet.SetFilePos(packet.GetFilePos() + strlen("thread:")); const lldb::tid_t tid = packet.GetHexMaxU64(false, 0); if (tid != 0) return m_debugged_process_up->GetThreadByID(tid); - return nullptr; + return thread_sp; } lldb::tid_t GDBRemoteCommunicationServerLLGS::GetCurrentThreadID() const { if (m_current_tid == 0 || m_current_tid == LLDB_INVALID_THREAD_ID) { - // Use whatever the debug process says is the current thread id since the - // protocol either didn't specify or specified we want any/all threads - // marked as the current thread. + // Use whatever the debug process says is the current thread id + // since the protocol either didn't specify or specified we want + // any/all threads marked as the current thread. if (!m_debugged_process_up) return LLDB_INVALID_THREAD_ID; return m_debugged_process_up->GetCurrentThreadID(); @@ -3218,7 +3307,7 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, if (m_debugged_process_up ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) .Success()) { - if (FileSystem::Instance().Exists(file_spec)) + if (file_spec.Exists()) return file_spec; } } diff --git a/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt b/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt index 5b138534404..f8c57cb9488 100644 --- a/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt +++ b/gnu/llvm/tools/lldb/tools/lldb-server/CMakeLists.txt @@ -24,6 +24,41 @@ endif () include_directories(../../source) +set(LLDB_SYSTEM_LIBS) +if (NOT LLDB_DISABLE_LIBEDIT) + list(APPEND LLDB_SYSTEM_LIBS edit) +endif() +if (NOT LLDB_DISABLE_CURSES) + list(APPEND LLDB_SYSTEM_LIBS ${CURSES_LIBRARIES}) + if(LLVM_ENABLE_TERMINFO AND HAVE_TERMINFO) + list(APPEND LLDB_SYSTEM_LIBS ${TERMINFO_LIBS}) + endif() +endif() + +if (NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB ) + list(APPEND LLDB_SYSTEM_LIBS atomic) +endif() + +# On FreeBSD/NetBSD backtrace() is provided by libexecinfo, not libc. +if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR CMAKE_SYSTEM_NAME MATCHES "NetBSD") + list(APPEND LLDB_SYSTEM_LIBS execinfo) +endif() + +if (NOT LLDB_DISABLE_PYTHON AND NOT LLVM_BUILD_STATIC) + list(APPEND LLDB_SYSTEM_LIBS ${PYTHON_LIBRARIES}) +endif() + +list(APPEND LLDB_SYSTEM_LIBS ${system_libs}) + +if (LLVM_BUILD_STATIC) + if (NOT LLDB_DISABLE_PYTHON) + list(APPEND LLDB_SYSTEM_LIBS python2.7 util) + endif() + if (NOT LLDB_DISABLE_CURSES) + list(APPEND LLDB_SYSTEM_LIBS gpm) + endif() +endif() + set(LLDB_PLUGINS) if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android") @@ -34,21 +69,12 @@ if(CMAKE_SYSTEM_NAME MATCHES "NetBSD") list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD) endif() -if(CMAKE_SYSTEM_NAME MATCHES "Darwin") - list(APPEND LLDB_PLUGINS lldbPluginObjectFileMachO) -elseif(CMAKE_SYSTEM_NAME MATCHES "Windows") - list(APPEND LLDB_PLUGINS lldbPluginObjectFilePECOFF) -else() - list(APPEND LLDB_PLUGINS lldbPluginObjectFileELF) -endif() - -add_lldb_tool(lldb-server +add_lldb_tool(lldb-server INCLUDE_IN_FRAMEWORK Acceptor.cpp lldb-gdbserver.cpp lldb-platform.cpp lldb-server.cpp LLDBServerUtilities.cpp - SystemInitializerLLGS.cpp LINK_LIBS lldbBase @@ -63,4 +89,4 @@ add_lldb_tool(lldb-server Support ) -target_link_libraries(lldb-server PRIVATE ${LLDB_SYSTEM_LIBS}) +target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS}) diff --git a/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp b/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp index 062bbd0c3b6..f1a9b113c8e 100644 --- a/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp +++ b/gnu/llvm/tools/lldb/tools/lldb-server/lldb-gdbserver.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +// C Includes #include <errno.h> #include <stdint.h> #include <stdio.h> @@ -18,6 +19,8 @@ #include <unistd.h> #endif +// C++ Includes + #include "Acceptor.h" #include "LLDBServerUtilities.h" @@ -25,7 +28,6 @@ #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" #include "lldb/Core/PluginManager.h" #include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostGetOpt.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/Pipe.h" @@ -104,7 +106,6 @@ static struct option g_long_options[] = { // than llgs listening for a connection from address on port. {"setsid", no_argument, NULL, 'S'}, // Call setsid() to make llgs run in its own session. - {"fd", required_argument, NULL, 'F'}, {NULL, 0, NULL, 0}}; //---------------------------------------------------------------------- @@ -131,13 +132,13 @@ static void display_usage(const char *progname, const char *subcommand) { "[--log-file log-file-name] " "[--log-channels log-channel-list] " "[--setsid] " - "[--fd file-descriptor]" "[--named-pipe named-pipe-path] " "[--native-regs] " "[--attach pid] " "[[HOST]:PORT] " "[-- PROGRAM ARG1 ARG2 ...]\n", progname, subcommand); + exit(0); } void handle_attach_to_pid(GDBRemoteCommunicationServerLLGS &gdb_server, @@ -175,27 +176,27 @@ void handle_attach(GDBRemoteCommunicationServerLLGS &gdb_server, void handle_launch(GDBRemoteCommunicationServerLLGS &gdb_server, int argc, const char *const argv[]) { - ProcessLaunchInfo info; - info.GetFlags().Set(eLaunchFlagStopAtEntry | eLaunchFlagDebug | - eLaunchFlagDisableASLR); - info.SetArguments(const_cast<const char **>(argv), true); - - llvm::SmallString<64> cwd; - if (std::error_code ec = llvm::sys::fs::current_path(cwd)) { - llvm::errs() << "Error getting current directory: " << ec.message() << "\n"; + Status error; + error = gdb_server.SetLaunchArguments(argv, argc); + if (error.Fail()) { + fprintf(stderr, "error: failed to set launch args for '%s': %s\n", argv[0], + error.AsCString()); exit(1); } - FileSpec cwd_spec(cwd); - FileSystem::Instance().Resolve(cwd_spec); - info.SetWorkingDirectory(cwd_spec); - info.GetEnvironment() = Host::GetEnvironment(); - gdb_server.SetLaunchInfo(info); + unsigned int launch_flags = eLaunchFlagStopAtEntry | eLaunchFlagDebug; + + error = gdb_server.SetLaunchFlags(launch_flags); + if (error.Fail()) { + fprintf(stderr, "error: failed to set launch flags for '%s': %s\n", argv[0], + error.AsCString()); + exit(1); + } - Status error = gdb_server.LaunchProcess(); + error = gdb_server.LaunchProcess(); if (error.Fail()) { - llvm::errs() << llvm::formatv("error: failed to launch '{0}': {1}\n", - argv[0], error); + fprintf(stderr, "error: failed to launch '%s': %s\n", argv[0], + error.AsCString()); exit(1); } } @@ -218,44 +219,23 @@ Status writeSocketIdToPipe(const char *const named_pipe_path, return writeSocketIdToPipe(port_name_pipe, socket_id); } -Status writeSocketIdToPipe(lldb::pipe_t unnamed_pipe, - const std::string &socket_id) { - Pipe port_pipe{LLDB_INVALID_PIPE, unnamed_pipe}; +Status writeSocketIdToPipe(int unnamed_pipe_fd, const std::string &socket_id) { +#if defined(_WIN32) + return Status("Unnamed pipes are not supported on Windows."); +#else + Pipe port_pipe{Pipe::kInvalidDescriptor, unnamed_pipe_fd}; return writeSocketIdToPipe(port_pipe, socket_id); +#endif } void ConnectToRemote(MainLoop &mainloop, GDBRemoteCommunicationServerLLGS &gdb_server, bool reverse_connect, const char *const host_and_port, const char *const progname, const char *const subcommand, - const char *const named_pipe_path, pipe_t unnamed_pipe, - int connection_fd) { + const char *const named_pipe_path, int unnamed_pipe_fd) { Status error; - std::unique_ptr<Connection> connection_up; - if (connection_fd != -1) { - // Build the connection string. - char connection_url[512]; - snprintf(connection_url, sizeof(connection_url), "fd://%d", connection_fd); - - // Create the connection. -#if !defined LLDB_DISABLE_POSIX && !defined _WIN32 - ::fcntl(connection_fd, F_SETFD, FD_CLOEXEC); -#endif - connection_up.reset(new ConnectionFileDescriptor); - auto connection_result = connection_up->Connect(connection_url, &error); - if (connection_result != eConnectionStatusSuccess) { - fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", - connection_url, static_cast<int>(connection_result)); - exit(-1); - } - if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", - connection_url, error.AsCString()); - exit(-1); - } - } else if (host_and_port && host_and_port[0]) { + if (host_and_port && host_and_port[0]) { // Parse out host and port. std::string final_host_and_port; std::string connection_host; @@ -275,6 +255,7 @@ void ConnectToRemote(MainLoop &mainloop, connection_portno = StringConvert::ToUInt32(connection_port.c_str(), 0); } + std::unique_ptr<Connection> connection_up; if (reverse_connect) { // llgs will connect to the gdb-remote client. @@ -282,7 +263,7 @@ void ConnectToRemote(MainLoop &mainloop, // Ensure we have a port number for the connection. if (connection_portno == 0) { fprintf(stderr, "error: port number must be specified on when using " - "reverse connect\n"); + "reverse connect"); exit(1); } @@ -296,12 +277,12 @@ void ConnectToRemote(MainLoop &mainloop, auto connection_result = connection_up->Connect(connection_url, &error); if (connection_result != eConnectionStatusSuccess) { fprintf(stderr, "error: failed to connect to client at '%s' " - "(connection status: %d)\n", + "(connection status: %d)", connection_url, static_cast<int>(connection_result)); exit(-1); } if (error.Fail()) { - fprintf(stderr, "error: failed to connect to client at '%s': %s\n", + fprintf(stderr, "error: failed to connect to client at '%s': %s", connection_url, error.AsCString()); exit(-1); } @@ -309,7 +290,7 @@ void ConnectToRemote(MainLoop &mainloop, std::unique_ptr<Acceptor> acceptor_up( Acceptor::Create(final_host_and_port, false, error)); if (error.Fail()) { - fprintf(stderr, "failed to create acceptor: %s\n", error.AsCString()); + fprintf(stderr, "failed to create acceptor: %s", error.AsCString()); exit(1); } error = acceptor_up->Listen(1); @@ -323,15 +304,15 @@ void ConnectToRemote(MainLoop &mainloop, if (named_pipe_path && named_pipe_path[0]) { error = writeSocketIdToPipe(named_pipe_path, socket_id); if (error.Fail()) - fprintf(stderr, "failed to write to the named pipe \'%s\': %s\n", + fprintf(stderr, "failed to write to the named pipe \'%s\': %s", named_pipe_path, error.AsCString()); } // If we have an unnamed pipe to write the socket id back to, do that // now. - else if (unnamed_pipe != LLDB_INVALID_PIPE) { - error = writeSocketIdToPipe(unnamed_pipe, socket_id); + else if (unnamed_pipe_fd >= 0) { + error = writeSocketIdToPipe(unnamed_pipe_fd, socket_id); if (error.Fail()) - fprintf(stderr, "failed to write to the unnamed pipe: %s\n", + fprintf(stderr, "failed to write to the unnamed pipe: %s", error.AsCString()); } } else { @@ -347,14 +328,14 @@ void ConnectToRemote(MainLoop &mainloop, } connection_up.reset(conn); } + error = gdb_server.InitializeConnection(std::move(connection_up)); + if (error.Fail()) { + fprintf(stderr, "Failed to initialize connection: %s\n", + error.AsCString()); + exit(-1); + } + printf("Connection established.\n"); } - error = gdb_server.InitializeConnection(std::move(connection_up)); - if (error.Fail()) { - fprintf(stderr, "Failed to initialize connection: %s\n", - error.AsCString()); - exit(-1); - } - printf("Connection established.\n"); } //---------------------------------------------------------------------- @@ -381,9 +362,8 @@ int main_gdbserver(int argc, char *argv[]) { std::string log_file; StringRef log_channels; // e.g. "lldb process threads:gdb-remote default:linux all" - lldb::pipe_t unnamed_pipe = LLDB_INVALID_PIPE; + int unnamed_pipe_fd = -1; bool reverse_connect = false; - int connection_fd = -1; // ProcessLaunchInfo launch_info; ProcessAttachInfo attach_info; @@ -422,7 +402,7 @@ int main_gdbserver(int argc, char *argv[]) { case 'U': // unnamed pipe if (optarg && optarg[0]) - unnamed_pipe = (pipe_t)StringConvert::ToUInt64(optarg, -1); + unnamed_pipe_fd = StringConvert::ToUInt32(optarg, -1); break; case 'r': @@ -433,10 +413,6 @@ int main_gdbserver(int argc, char *argv[]) { reverse_connect = true; break; - case 'F': - connection_fd = StringConvert::ToUInt32(optarg, -1); - break; - #ifndef _WIN32 case 'S': // Put llgs into a new session. Terminals group processes @@ -496,8 +472,7 @@ int main_gdbserver(int argc, char *argv[]) { argc -= optind; argv += optind; - if (argc == 0 && connection_fd == -1) { - fputs("No arguments\n", stderr); + if (argc == 0) { display_usage(progname, subcommand); exit(255); } @@ -525,8 +500,8 @@ int main_gdbserver(int argc, char *argv[]) { printf("%s-%s", LLGS_PROGRAM_NAME, LLGS_VERSION_STR); ConnectToRemote(mainloop, gdb_server, reverse_connect, host_and_port, - progname, subcommand, named_pipe_path.c_str(), - unnamed_pipe, connection_fd); + progname, subcommand, named_pipe_path.c_str(), + unnamed_pipe_fd); if (!gdb_server.IsConnected()) { fprintf(stderr, "no connection information provided, unable to run\n"); |