summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-02 18:31:19 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-02 18:31:19 +0000
commit773dd0e6e632d48d7123a321ba86f50847b9afc0 (patch)
treec6bd992bb1963df11f8de346d12a5a70c2e4deb2
parent5060b64b7d79491d507a75201be161fd0c38fcbb (diff)
Notes
-rw-r--r--CMakeLists.txt13
-rw-r--r--cmake/XcodeHeaderGenerator/CMakeLists.txt14
-rw-r--r--cmake/modules/LLDBConfig.cmake18
-rw-r--r--cmake/modules/LLDBGenerateConfig.cmake35
-rw-r--r--include/lldb/Core/Module.h2
-rw-r--r--include/lldb/Core/TraceOptions.h2
-rw-r--r--include/lldb/Core/UniqueCStringMap.h42
-rw-r--r--include/lldb/Host/Config.h4
-rw-r--r--include/lldb/Host/Config.h.cmake4
-rw-r--r--include/lldb/Host/MainLoop.h96
-rw-r--r--include/lldb/Host/PosixApi.h4
-rw-r--r--include/lldb/Host/Socket.h7
-rw-r--r--include/lldb/Host/common/TCPSocket.h22
-rw-r--r--include/lldb/Host/common/UDPSocket.h9
-rw-r--r--include/lldb/Host/linux/AbstractSocket.h2
-rw-r--r--include/lldb/Host/posix/DomainSocket.h10
-rw-r--r--include/lldb/Host/posix/MainLoopPosix.h104
-rw-r--r--include/lldb/Symbol/ObjectFile.h4
-rw-r--r--include/lldb/Symbol/SymbolFile.h2
-rw-r--r--include/lldb/Symbol/Symtab.h1
-rw-r--r--include/lldb/Target/Target.h4
-rw-r--r--lldb.xcodeproj/project.pbxproj24
-rw-r--r--packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py21
-rw-r--r--packages/Python/lldbsuite/test/make/Android.rules1
-rw-r--r--packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py12
-rw-r--r--source/Core/Module.cpp16
-rw-r--r--source/Host/CMakeLists.txt2
-rw-r--r--source/Host/common/MainLoop.cpp382
-rw-r--r--source/Host/common/Socket.cpp38
-rw-r--r--source/Host/common/SocketAddress.cpp9
-rw-r--r--source/Host/common/TCPSocket.cpp256
-rw-r--r--source/Host/common/UDPSocket.cpp84
-rw-r--r--source/Host/linux/AbstractSocket.cpp4
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp4
-rw-r--r--source/Host/posix/DomainSocket.cpp35
-rw-r--r--source/Host/posix/MainLoopPosix.cpp182
-rw-r--r--source/Interpreter/CommandInterpreter.cpp4
-rw-r--r--source/Interpreter/OptionValueEnumeration.cpp15
-rw-r--r--source/Interpreter/OptionValueProperties.cpp10
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp138
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h12
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp18
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp66
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVector.cpp19
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp7
-rw-r--r--source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp5
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp6
-rw-r--r--source/Plugins/ObjectFile/ELF/ObjectFileELF.h2
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp18
-rw-r--r--source/Plugins/SymbolFile/DWARF/NameToDIE.cpp12
-rw-r--r--source/Plugins/SymbolFile/DWARF/NameToDIE.h3
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp6
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h2
-rw-r--r--source/Symbol/ClangASTContext.cpp122
-rw-r--r--source/Symbol/GoASTContext.cpp35
-rw-r--r--source/Symbol/SymbolFile.cpp4
-rw-r--r--source/Symbol/Symtab.cpp68
-rw-r--r--source/Target/Target.cpp19
-rw-r--r--source/Utility/ConstString.cpp29
-rw-r--r--tools/debugserver/debugserver.xcodeproj/project.pbxproj4
-rw-r--r--tools/debugserver/source/CMakeLists.txt1
-rw-r--r--tools/debugserver/source/RNBSocket.cpp246
-rw-r--r--tools/debugserver/source/debugserver.cpp16
-rw-r--r--tools/lldb-server/Acceptor.cpp3
-rw-r--r--unittests/Host/SocketTest.cpp21
-rw-r--r--unittests/ObjectFile/ELF/CMakeLists.txt10
-rw-r--r--unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml50
-rw-r--r--unittests/ObjectFile/ELF/TestObjectFileELF.cpp105
-rw-r--r--unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp5
-rw-r--r--unittests/debugserver/RNBSocketTest.cpp31
71 files changed, 1543 insertions, 1040 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fe640fedb038..ada293811b3e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,15 @@
cmake_minimum_required(VERSION 3.4.3)
-include(cmake/modules/LLDBStandalone.cmake)
-include(cmake/modules/LLDBConfig.cmake)
-include(cmake/modules/AddLLDB.cmake)
+# Add path for custom modules
+set(CMAKE_MODULE_PATH
+ ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
+ )
+
+include(LLDBStandalone)
+include(LLDBConfig)
+include(AddLLDB)
if (CMAKE_SYSTEM_NAME MATCHES "Windows|Android")
set(LLDB_DEFAULT_DISABLE_LIBEDIT 1)
diff --git a/cmake/XcodeHeaderGenerator/CMakeLists.txt b/cmake/XcodeHeaderGenerator/CMakeLists.txt
new file mode 100644
index 000000000000..f515c5fb8c46
--- /dev/null
+++ b/cmake/XcodeHeaderGenerator/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.4.3)
+
+project(XcodeConfig C CXX)
+
+set(CMAKE_MODULE_PATH
+ ${CMAKE_MODULE_PATH}
+ "${CMAKE_CURRENT_SOURCE_DIR}/.."
+ "${CMAKE_CURRENT_SOURCE_DIR}/../modules"
+ )
+
+set(LLDB_CONFIG_HEADER_INPUT
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/lldb/Host/Config.h.cmake)
+
+include(LLDBGenerateConfig)
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake
index c40a24f056d8..609851f46e49 100644
--- a/cmake/modules/LLDBConfig.cmake
+++ b/cmake/modules/LLDBConfig.cmake
@@ -426,20 +426,4 @@ if ((CMAKE_SYSTEM_NAME MATCHES "Android") AND LLVM_BUILD_STATIC AND
endif()
find_package(Backtrace)
-
-include(CheckIncludeFile)
-check_include_file(termios.h HAVE_TERMIOS_H)
-check_include_file(sys/event.h HAVE_SYS_EVENT_H)
-
-# These checks exist in LLVM's configuration, so I want to match the LLVM names
-# so that the check isn't duplicated, but we translate them into the LLDB names
-# so that I don't have to change all the uses at the moment.
-set(LLDB_CONFIG_TERMIOS_SUPPORTED ${HAVE_TERMIOS_H})
-if(NOT UNIX)
- set(LLDB_DISABLE_POSIX 1)
-endif()
-
-# This should be done at the end
-configure_file(
- ${LLDB_INCLUDE_ROOT}/lldb/Host/Config.h.cmake
- ${CMAKE_CURRENT_BINARY_DIR}/include/lldb/Host/Config.h)
+include(LLDBGenerateConfig)
diff --git a/cmake/modules/LLDBGenerateConfig.cmake b/cmake/modules/LLDBGenerateConfig.cmake
new file mode 100644
index 000000000000..f812cf11614a
--- /dev/null
+++ b/cmake/modules/LLDBGenerateConfig.cmake
@@ -0,0 +1,35 @@
+# This file contains all the logic for running configure-time checks
+
+include(CheckSymbolExists)
+include(CheckIncludeFile)
+include(CheckIncludeFiles)
+
+set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
+check_symbol_exists(ppoll poll.h HAVE_PPOLL)
+set(CMAKE_REQUIRED_DEFINITIONS)
+check_symbol_exists(sigaction signal.h HAVE_SIGACTION)
+
+check_include_file(termios.h HAVE_TERMIOS_H)
+check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H)
+
+# These checks exist in LLVM's configuration, so I want to match the LLVM names
+# so that the check isn't duplicated, but we translate them into the LLDB names
+# so that I don't have to change all the uses at the moment.
+set(LLDB_CONFIG_TERMIOS_SUPPORTED ${HAVE_TERMIOS_H})
+if(NOT UNIX)
+ set(LLDB_DISABLE_POSIX 1)
+endif()
+
+if(NOT LLDB_CONFIG_HEADER_INPUT)
+ set(LLDB_CONFIG_HEADER_INPUT ${LLDB_INCLUDE_ROOT}/lldb/Host/Config.h.cmake)
+endif()
+
+if(NOT LLDB_CONFIG_HEADER_OUTPUT)
+ set(LLDB_CONFIG_HEADER_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/include/lldb/Host/Config.h)
+endif()
+
+# This should be done at the end
+configure_file(
+ ${LLDB_CONFIG_HEADER_INPUT}
+ ${LLDB_CONFIG_HEADER_OUTPUT}
+ )
diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h
index ca47a38a2ef5..33735bc99f60 100644
--- a/include/lldb/Core/Module.h
+++ b/include/lldb/Core/Module.h
@@ -614,6 +614,8 @@ public:
const FileSpec &GetSymbolFileFileSpec() const { return m_symfile_spec; }
+ void PreloadSymbols();
+
void SetSymbolFileFileSpec(const FileSpec &file);
const llvm::sys::TimePoint<> &GetModificationTime() const {
diff --git a/include/lldb/Core/TraceOptions.h b/include/lldb/Core/TraceOptions.h
index ffa2bae7f659..e875a531e870 100644
--- a/include/lldb/Core/TraceOptions.h
+++ b/include/lldb/Core/TraceOptions.h
@@ -59,4 +59,4 @@ private:
};
}
-#endif // liblldb_TraceOptions_h_ \ No newline at end of file
+#endif // liblldb_TraceOptions_h_
diff --git a/include/lldb/Core/UniqueCStringMap.h b/include/lldb/Core/UniqueCStringMap.h
index 1475fdaa74d9..e8c6c7c1353e 100644
--- a/include/lldb/Core/UniqueCStringMap.h
+++ b/include/lldb/Core/UniqueCStringMap.h
@@ -17,10 +17,9 @@
// Other libraries and framework includes
// Project includes
+#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/RegularExpression.h"
-#include "llvm/ADT/StringRef.h"
-
namespace lldb_private {
//----------------------------------------------------------------------
@@ -37,13 +36,17 @@ public:
struct Entry {
Entry() {}
- Entry(llvm::StringRef cstr) : cstring(cstr), value() {}
+ Entry(ConstString cstr) : cstring(cstr), value() {}
- Entry(llvm::StringRef cstr, const T &v) : cstring(cstr), value(v) {}
+ Entry(ConstString cstr, const T &v) : cstring(cstr), value(v) {}
- bool operator<(const Entry &rhs) const { return cstring < rhs.cstring; }
+ // This is only for uniqueness, not lexicographical ordering, so we can
+ // just compare pointers.
+ bool operator<(const Entry &rhs) const {
+ return cstring.GetCString() < rhs.cstring.GetCString();
+ }
- llvm::StringRef cstring;
+ ConstString cstring;
T value;
};
@@ -52,7 +55,7 @@ public:
// this map, then later call UniqueCStringMap<T>::Sort() before doing
// any searches by name.
//------------------------------------------------------------------
- void Append(llvm::StringRef unique_cstr, const T &value) {
+ void Append(ConstString unique_cstr, const T &value) {
m_map.push_back(typename UniqueCStringMap<T>::Entry(unique_cstr, value));
}
@@ -64,7 +67,7 @@ public:
// Call this function to always keep the map sorted when putting
// entries into the map.
//------------------------------------------------------------------
- void Insert(llvm::StringRef unique_cstr, const T &value) {
+ void Insert(ConstString unique_cstr, const T &value) {
typename UniqueCStringMap<T>::Entry e(unique_cstr, value);
m_map.insert(std::upper_bound(m_map.begin(), m_map.end(), e), e);
}
@@ -87,7 +90,7 @@ public:
return false;
}
- llvm::StringRef GetCStringAtIndexUnchecked(uint32_t idx) const {
+ ConstString GetCStringAtIndexUnchecked(uint32_t idx) const {
return m_map[idx].cstring;
}
@@ -101,8 +104,8 @@ public:
return m_map[idx].value;
}
- llvm::StringRef GetCStringAtIndex(uint32_t idx) const {
- return ((idx < m_map.size()) ? m_map[idx].cstring : llvm::StringRef());
+ ConstString GetCStringAtIndex(uint32_t idx) const {
+ return ((idx < m_map.size()) ? m_map[idx].cstring : ConstString());
}
//------------------------------------------------------------------
@@ -113,7 +116,7 @@ public:
// T values and only if there is a sensible failure value that can
// be returned and that won't match any existing values.
//------------------------------------------------------------------
- T Find(llvm::StringRef unique_cstr, T fail_value) const {
+ T Find(ConstString unique_cstr, T fail_value) const {
Entry search_entry(unique_cstr);
const_iterator end = m_map.end();
const_iterator pos = std::lower_bound(m_map.begin(), end, search_entry);
@@ -131,15 +134,12 @@ public:
// The caller is responsible for ensuring that the collection does
// not change during while using the returned pointer.
//------------------------------------------------------------------
- const Entry *FindFirstValueForName(llvm::StringRef unique_cstr) const {
+ const Entry *FindFirstValueForName(ConstString unique_cstr) const {
Entry search_entry(unique_cstr);
const_iterator end = m_map.end();
const_iterator pos = std::lower_bound(m_map.begin(), end, search_entry);
- if (pos != end) {
- llvm::StringRef pos_cstr = pos->cstring;
- if (pos_cstr == unique_cstr)
- return &(*pos);
- }
+ if (pos != end && pos->cstring == unique_cstr)
+ return &(*pos);
return nullptr;
}
@@ -164,7 +164,7 @@ public:
return nullptr;
}
- size_t GetValues(llvm::StringRef unique_cstr, std::vector<T> &values) const {
+ size_t GetValues(ConstString unique_cstr, std::vector<T> &values) const {
const size_t start_size = values.size();
Entry search_entry(unique_cstr);
@@ -186,7 +186,7 @@ public:
const_iterator pos, end = m_map.end();
for (pos = m_map.begin(); pos != end; ++pos) {
- if (regex.Execute(pos->cstring))
+ if (regex.Execute(pos->cstring.GetCString()))
values.push_back(pos->value);
}
@@ -240,7 +240,7 @@ public:
}
}
- size_t Erase(llvm::StringRef unique_cstr) {
+ size_t Erase(ConstString unique_cstr) {
size_t num_removed = 0;
Entry search_entry(unique_cstr);
iterator end = m_map.end();
diff --git a/include/lldb/Host/Config.h b/include/lldb/Host/Config.h
index 95d0191397b3..3fa19e77452d 100644
--- a/include/lldb/Host/Config.h
+++ b/include/lldb/Host/Config.h
@@ -18,6 +18,10 @@
#define HAVE_SYS_EVENT_H 1
+#define HAVE_PPOLL 0
+
+#define HAVE_SIGACTION 1
+
#else
#error This file is only used by the Xcode build.
diff --git a/include/lldb/Host/Config.h.cmake b/include/lldb/Host/Config.h.cmake
index d072c1a08687..5a16425fe0a9 100644
--- a/include/lldb/Host/Config.h.cmake
+++ b/include/lldb/Host/Config.h.cmake
@@ -16,4 +16,8 @@
#cmakedefine01 HAVE_SYS_EVENT_H
+#cmakedefine01 HAVE_PPOLL
+
+#cmakedefine01 HAVE_SIGACTION
+
#endif // #ifndef LLDB_HOST_CONFIG_H
diff --git a/include/lldb/Host/MainLoop.h b/include/lldb/Host/MainLoop.h
index 8aa26b63183a..79370bf8461f 100644
--- a/include/lldb/Host/MainLoop.h
+++ b/include/lldb/Host/MainLoop.h
@@ -10,16 +10,96 @@
#ifndef lldb_Host_MainLoop_h_
#define lldb_Host_MainLoop_h_
-#ifdef _WIN32
+#include "lldb/Host/Config.h"
#include "lldb/Host/MainLoopBase.h"
+
+#include "llvm/ADT/DenseMap.h"
+
+#if !HAVE_PPOLL && !HAVE_SYS_EVENT_H
+#define SIGNAL_POLLING_UNSUPPORTED 1
+#endif
+
namespace lldb_private {
-typedef MainLoopBase MainLoop;
-}
-#else
-#include "lldb/Host/posix/MainLoopPosix.h"
-namespace lldb_private {
-typedef MainLoopPosix MainLoop;
-}
+
+// Implementation of the MainLoopBase class. It can monitor file descriptors for
+// readability using ppoll, kqueue, poll or WSAPoll. On Windows it only supports
+// polling sockets, and will not work on generic file handles or pipes. On
+// systems without kqueue or ppoll handling singnals is not supported. In
+// addition to the common base, this class provides the ability to invoke a
+// given handler when a signal is received.
+//
+// Since this class is primarily intended to be used for single-threaded
+// processing, it does not attempt to perform any internal synchronisation and
+// any concurrent accesses must be protected externally. However, it is
+// perfectly legitimate to have more than one instance of this class running on
+// separate threads, or even a single thread (with some limitations on signal
+// monitoring).
+// TODO: Add locking if this class is to be used in a multi-threaded context.
+class MainLoop : public MainLoopBase {
+private:
+ class SignalHandle;
+
+public:
+ typedef std::unique_ptr<SignalHandle> SignalHandleUP;
+
+ ~MainLoop() override;
+
+ ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
+ const Callback &callback,
+ Error &error) override;
+
+ // Listening for signals from multiple MainLoop instances is perfectly safe as
+ // long as they don't try to listen for the same signal. The callback function
+ // is invoked when the control returns to the Run() function, not when the
+ // hander is executed. This mean that you can treat the callback as a normal
+ // function and perform things which would not be safe in a signal handler.
+ // However, since the callback is not invoked synchronously, you cannot use
+ // this mechanism to handle SIGSEGV and the like.
+ SignalHandleUP RegisterSignal(int signo, const Callback &callback,
+ Error &error);
+
+ Error Run() override;
+
+ // This should only be performed from a callback. Do not attempt to terminate
+ // the processing from another thread.
+ // TODO: Add synchronization if we want to be terminated from another thread.
+ void RequestTermination() override { m_terminate_request = true; }
+
+protected:
+ void UnregisterReadObject(IOObject::WaitableHandle handle) override;
+
+ void UnregisterSignal(int signo);
+
+private:
+ class SignalHandle {
+ public:
+ ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); }
+
+ private:
+ SignalHandle(MainLoop &mainloop, int signo)
+ : m_mainloop(mainloop), m_signo(signo) {}
+
+ MainLoop &m_mainloop;
+ int m_signo;
+
+ friend class MainLoop;
+ DISALLOW_COPY_AND_ASSIGN(SignalHandle);
+ };
+
+ struct SignalInfo {
+ Callback callback;
+#if HAVE_SIGACTION
+ struct sigaction old_action;
#endif
+ bool was_blocked : 1;
+ };
+ class RunImpl;
+
+ llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
+ llvm::DenseMap<int, SignalInfo> m_signals;
+ bool m_terminate_request : 1;
+};
+
+} // namespace lldb_private
#endif // lldb_Host_MainLoop_h_
diff --git a/include/lldb/Host/PosixApi.h b/include/lldb/Host/PosixApi.h
index 23a291c401de..02324307dc9e 100644
--- a/include/lldb/Host/PosixApi.h
+++ b/include/lldb/Host/PosixApi.h
@@ -14,9 +14,7 @@
// to provide a minimum level of compatibility across all platforms to rely
// on various posix api functionality.
-#include "llvm/Support/Compiler.h"
-
-#if defined(LLVM_ON_WIN32)
+#if defined(_WIN32)
#include "lldb/Host/windows/PosixApi.h"
#endif
diff --git a/include/lldb/Host/Socket.h b/include/lldb/Host/Socket.h
index 386133e96952..36d506281cf8 100644
--- a/include/lldb/Host/Socket.h
+++ b/include/lldb/Host/Socket.h
@@ -57,8 +57,7 @@ public:
virtual Error Connect(llvm::StringRef name) = 0;
virtual Error Listen(llvm::StringRef name, int backlog) = 0;
- virtual Error Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) = 0;
+ virtual Error Accept(Socket *&socket) = 0;
// Initialize a Tcp Socket object in listening mode. listen and accept are
// implemented
@@ -103,7 +102,8 @@ public:
int32_t &port, Error *error_ptr);
protected:
- Socket(NativeSocket socket, SocketProtocol protocol, bool should_close);
+ Socket(SocketProtocol protocol, bool should_close,
+ bool m_child_process_inherit);
virtual size_t Send(const void *buf, const size_t num_bytes);
@@ -117,6 +117,7 @@ protected:
SocketProtocol m_protocol;
NativeSocket m_socket;
+ bool m_child_processes_inherit;
};
} // namespace lldb_private
diff --git a/include/lldb/Host/common/TCPSocket.h b/include/lldb/Host/common/TCPSocket.h
index 2ce8d824f0a0..5b72f344019f 100644
--- a/include/lldb/Host/common/TCPSocket.h
+++ b/include/lldb/Host/common/TCPSocket.h
@@ -11,12 +11,16 @@
#define liblldb_TCPSocket_h_
#include "lldb/Host/Socket.h"
+#include "lldb/Host/SocketAddress.h"
+#include <map>
namespace lldb_private {
class TCPSocket : public Socket {
public:
- TCPSocket(NativeSocket socket, bool should_close);
- TCPSocket(bool child_processes_inherit, Error &error);
+ TCPSocket(bool should_close, bool child_processes_inherit);
+ TCPSocket(NativeSocket socket, bool should_close,
+ bool child_processes_inherit);
+ ~TCPSocket() override;
// returns port number or 0 if error
uint16_t GetLocalPortNumber() const;
@@ -37,8 +41,18 @@ public:
Error Connect(llvm::StringRef name) override;
Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&conn_socket) override;
+ Error Accept(Socket *&conn_socket) override;
+
+ Error CreateSocket(int domain);
+
+ bool IsValid() const override;
+
+private:
+ TCPSocket(NativeSocket socket, const TCPSocket &listen_socket);
+
+ void CloseListenSockets();
+
+ std::map<int, SocketAddress> m_listen_sockets;
};
}
diff --git a/include/lldb/Host/common/UDPSocket.h b/include/lldb/Host/common/UDPSocket.h
index 507c9827caf6..38524fa8f62b 100644
--- a/include/lldb/Host/common/UDPSocket.h
+++ b/include/lldb/Host/common/UDPSocket.h
@@ -15,19 +15,20 @@
namespace lldb_private {
class UDPSocket : public Socket {
public:
- UDPSocket(bool child_processes_inherit, Error &error);
+ UDPSocket(bool should_close, bool child_processes_inherit);
static Error Connect(llvm::StringRef name, bool child_processes_inherit,
Socket *&socket);
private:
- UDPSocket(NativeSocket socket);
+ UDPSocket(NativeSocket socket, const UDPSocket &listen_socket);
size_t Send(const void *buf, const size_t num_bytes) override;
Error Connect(llvm::StringRef name) override;
Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) override;
+ Error Accept(Socket *&socket) override;
+
+ Error CreateSocket();
SocketAddress m_sockaddr;
};
diff --git a/include/lldb/Host/linux/AbstractSocket.h b/include/lldb/Host/linux/AbstractSocket.h
index f73a287cb3f8..3b38cde05522 100644
--- a/include/lldb/Host/linux/AbstractSocket.h
+++ b/include/lldb/Host/linux/AbstractSocket.h
@@ -15,7 +15,7 @@
namespace lldb_private {
class AbstractSocket : public DomainSocket {
public:
- AbstractSocket(bool child_processes_inherit, Error &error);
+ AbstractSocket(bool child_processes_inherit);
protected:
size_t GetNameOffset() const override;
diff --git a/include/lldb/Host/posix/DomainSocket.h b/include/lldb/Host/posix/DomainSocket.h
index 3bd4e0141336..78a3dc89828a 100644
--- a/include/lldb/Host/posix/DomainSocket.h
+++ b/include/lldb/Host/posix/DomainSocket.h
@@ -15,22 +15,20 @@
namespace lldb_private {
class DomainSocket : public Socket {
public:
- DomainSocket(bool child_processes_inherit, Error &error);
+ DomainSocket(bool should_close, bool child_processes_inherit);
Error Connect(llvm::StringRef name) override;
Error Listen(llvm::StringRef name, int backlog) override;
- Error Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) override;
+ Error Accept(Socket *&socket) override;
protected:
- DomainSocket(SocketProtocol protocol, bool child_processes_inherit,
- Error &error);
+ DomainSocket(SocketProtocol protocol, bool child_processes_inherit);
virtual size_t GetNameOffset() const;
virtual void DeleteSocketFile(llvm::StringRef name);
private:
- DomainSocket(NativeSocket socket);
+ DomainSocket(NativeSocket socket, const DomainSocket &listen_socket);
};
}
diff --git a/include/lldb/Host/posix/MainLoopPosix.h b/include/lldb/Host/posix/MainLoopPosix.h
deleted file mode 100644
index 21e02becf872..000000000000
--- a/include/lldb/Host/posix/MainLoopPosix.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===-- MainLoopPosix.h -----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef lldb_Host_posix_MainLoopPosix_h_
-#define lldb_Host_posix_MainLoopPosix_h_
-
-#include "lldb/Host/MainLoopBase.h"
-
-#include "llvm/ADT/DenseMap.h"
-
-namespace lldb_private {
-
-// Posix implementation of the MainLoopBase class. It can monitor file
-// descriptors for
-// readability using pselect. In addition to the common base, this class
-// provides the ability to
-// invoke a given handler when a signal is received.
-//
-// Since this class is primarily intended to be used for single-threaded
-// processing, it does not
-// attempt to perform any internal synchronisation and any concurrent accesses
-// must be protected
-// externally. However, it is perfectly legitimate to have more than one
-// instance of this class
-// running on separate threads, or even a single thread (with some limitations
-// on signal
-// monitoring).
-// TODO: Add locking if this class is to be used in a multi-threaded context.
-class MainLoopPosix : public MainLoopBase {
-private:
- class SignalHandle;
-
-public:
- typedef std::unique_ptr<SignalHandle> SignalHandleUP;
-
- ~MainLoopPosix() override;
-
- ReadHandleUP RegisterReadObject(const lldb::IOObjectSP &object_sp,
- const Callback &callback,
- Error &error) override;
-
- // Listening for signals from multiple MainLoopPosix instances is perfectly
- // safe as long as they
- // don't try to listen for the same signal. The callback function is invoked
- // when the control
- // returns to the Run() function, not when the hander is executed. This means
- // that you can
- // treat the callback as a normal function and perform things which would not
- // be safe in a
- // signal handler. However, since the callback is not invoked synchronously,
- // you cannot use
- // this mechanism to handle SIGSEGV and the like.
- SignalHandleUP RegisterSignal(int signo, const Callback &callback,
- Error &error);
-
- Error Run() override;
-
- // This should only be performed from a callback. Do not attempt to terminate
- // the processing
- // from another thread.
- // TODO: Add synchronization if we want to be terminated from another thread.
- void RequestTermination() override { m_terminate_request = true; }
-
-protected:
- void UnregisterReadObject(IOObject::WaitableHandle handle) override;
-
- void UnregisterSignal(int signo);
-
-private:
- class SignalHandle {
- public:
- ~SignalHandle() { m_mainloop.UnregisterSignal(m_signo); }
-
- private:
- SignalHandle(MainLoopPosix &mainloop, int signo)
- : m_mainloop(mainloop), m_signo(signo) {}
-
- MainLoopPosix &m_mainloop;
- int m_signo;
-
- friend class MainLoopPosix;
- DISALLOW_COPY_AND_ASSIGN(SignalHandle);
- };
-
- struct SignalInfo {
- Callback callback;
- struct sigaction old_action;
- bool was_blocked : 1;
- };
-
- llvm::DenseMap<IOObject::WaitableHandle, Callback> m_read_fds;
- llvm::DenseMap<int, SignalInfo> m_signals;
- bool m_terminate_request : 1;
-};
-
-} // namespace lldb_private
-
-#endif // lldb_Host_posix_MainLoopPosix_h_
diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h
index 03564eca4b58..296c9ff2129f 100644
--- a/include/lldb/Symbol/ObjectFile.h
+++ b/include/lldb/Symbol/ObjectFile.h
@@ -805,9 +805,9 @@ public:
bool IsInMemory() const { return m_memory_addr != LLDB_INVALID_ADDRESS; }
// Strip linker annotations (such as @@VERSION) from symbol names.
- virtual std::string
+ virtual llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
- return symbol_name.str();
+ return symbol_name;
}
static lldb::SymbolType GetSymbolTypeFromName(
diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h
index 34ae8d76e195..69110dc68cd7 100644
--- a/include/lldb/Symbol/SymbolFile.h
+++ b/include/lldb/Symbol/SymbolFile.h
@@ -180,6 +180,8 @@ public:
uint32_t type_mask,
lldb_private::TypeList &type_list) = 0;
+ virtual void PreloadSymbols();
+
virtual lldb_private::TypeSystem *
GetTypeSystemForLanguage(lldb::LanguageType language);
diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h
index 6a8d62cea8b7..3d24862af365 100644
--- a/include/lldb/Symbol/Symtab.h
+++ b/include/lldb/Symbol/Symtab.h
@@ -40,6 +40,7 @@ public:
Symtab(ObjectFile *objfile);
~Symtab();
+ void PreloadSymbols();
void Reserve(size_t count);
Symbol *Resize(size_t count);
uint32_t AddSymbol(const Symbol &symbol);
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
index 8d6fc772c887..8aa263f59254 100644
--- a/include/lldb/Target/Target.h
+++ b/include/lldb/Target/Target.h
@@ -82,6 +82,10 @@ public:
bool SetPreferDynamicValue(lldb::DynamicValueType d);
+ bool GetPreloadSymbols() const;
+
+ void SetPreloadSymbols(bool b);
+
bool GetDisableASLR() const;
void SetDisableASLR(bool b);
diff --git a/lldb.xcodeproj/project.pbxproj b/lldb.xcodeproj/project.pbxproj
index 6bcd8619f0b6..e988dba59992 100644
--- a/lldb.xcodeproj/project.pbxproj
+++ b/lldb.xcodeproj/project.pbxproj
@@ -665,7 +665,6 @@
26FFC19D14FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26FFC19714FC072100087D58 /* DynamicLoaderPOSIXDYLD.cpp */; };
304B2E461CAAA57B007829FE /* ClangUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3032B1B61CAAA3D1004BE1AB /* ClangUtil.cpp */; };
30B38A001CAAA6D7009524E3 /* ClangUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = 3032B1B91CAAA400004BE1AB /* ClangUtil.h */; };
- 30DED5DE1B4ECB49004CC508 /* MainLoopPosix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */; };
332CCB181AFF41620034D4C4 /* SBLanguageRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 3392EBB71AFF402200858B9F /* SBLanguageRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; };
33E5E8471A674FB60024ED68 /* StringConvert.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33E5E8411A672A240024ED68 /* StringConvert.cpp */; };
3F8160A61AB9F7DD001DA9DF /* Logging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3F8160A51AB9F7DD001DA9DF /* Logging.cpp */; };
@@ -868,6 +867,8 @@
9A0FDEA71E8EF5110086B2F5 /* RegisterContextLinux_mips.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A0FDE971E8EF5010086B2F5 /* RegisterContextLinux_mips.cpp */; };
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A19A6AD1163BB9800E0D453 /* SBValue.cpp */; };
+ 9A1E595C1EB2B141002206A5 /* SBTrace.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A1E59521EB2B0B9002206A5 /* SBTrace.cpp */; };
+ 9A1E595D1EB2B141002206A5 /* SBTraceOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A1E59531EB2B0B9002206A5 /* SBTraceOptions.cpp */; };
9A22A161135E30370024DDC3 /* EmulateInstructionARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A22A15D135E30370024DDC3 /* EmulateInstructionARM.cpp */; };
9A22A163135E30370024DDC3 /* EmulationStateARM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A22A15F135E30370024DDC3 /* EmulationStateARM.cpp */; };
9A357583116CFDEE00E8ED2F /* SBValueList.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A357582116CFDEE00E8ED2F /* SBValueList.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -876,6 +877,8 @@
9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A357672116E7B6400E8ED2F /* SBStringList.cpp */; };
9A3576A8116E9AB700E8ED2F /* SBHostOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A3576A7116E9AB700E8ED2F /* SBHostOS.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A3576A9116E9AC700E8ED2F /* SBHostOS.cpp */; };
+ 9A36D24D1EB3BE7F00AAD9EA /* SBTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A1E59581EB2B10D002206A5 /* SBTrace.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 9A36D24E1EB3BE7F00AAD9EA /* SBTraceOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A1E59591EB2B10D002206A5 /* SBTraceOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9A4F35101368A51A00823F52 /* StreamAsynchronousIO.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A4F350F1368A51A00823F52 /* StreamAsynchronousIO.cpp */; };
9A77AD541E64E2760025CE04 /* RegisterInfoPOSIX_arm.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9A77AD501E64E24E0025CE04 /* RegisterInfoPOSIX_arm.cpp */; };
9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9AC7038D117674EB0086C050 /* SBInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -978,6 +981,7 @@
B2A58724143119D50092BFBA /* SBWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2A58723143119D50092BFBA /* SBWatchpoint.cpp */; };
B2B7CCEB15D1BD6700EEFB57 /* CommandObjectWatchpointCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2B7CCEA15D1BD6600EEFB57 /* CommandObjectWatchpointCommand.cpp */; };
B2B7CCF015D1C20F00EEFB57 /* WatchpointOptions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B2B7CCEF15D1C20F00EEFB57 /* WatchpointOptions.cpp */; };
+ D67521381EA17C4200439694 /* MainLoop.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D67521351EA17C3900439694 /* MainLoop.cpp */; };
E769331C1A94D15400C73337 /* lldb-gdbserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26D6F3F4183E7F9300194858 /* lldb-gdbserver.cpp */; };
E769331E1A94D18100C73337 /* lldb-server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E769331D1A94D18100C73337 /* lldb-server.cpp */; };
E7723D441AC4A7FB002BA082 /* RegisterContextPOSIXCore_arm64.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E7723D421AC4A7FB002BA082 /* RegisterContextPOSIXCore_arm64.cpp */; };
@@ -2319,7 +2323,6 @@
26FFC19814FC072100087D58 /* DynamicLoaderPOSIXDYLD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DynamicLoaderPOSIXDYLD.h; sourceTree = "<group>"; };
3032B1B61CAAA3D1004BE1AB /* ClangUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangUtil.cpp; path = source/Symbol/ClangUtil.cpp; sourceTree = "<group>"; };
3032B1B91CAAA400004BE1AB /* ClangUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangUtil.h; path = include/lldb/Symbol/ClangUtil.h; sourceTree = "<group>"; };
- 30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainLoopPosix.cpp; sourceTree = "<group>"; };
33064C991A5C7A330033D415 /* UriParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UriParser.cpp; path = source/Utility/UriParser.cpp; sourceTree = "<group>"; };
3392EBB71AFF402200858B9F /* SBLanguageRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBLanguageRuntime.h; path = include/lldb/API/SBLanguageRuntime.h; sourceTree = "<group>"; };
33E5E8411A672A240024ED68 /* StringConvert.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringConvert.cpp; sourceTree = "<group>"; };
@@ -2810,6 +2813,10 @@
9A0FDE9B1E8EF5010086B2F5 /* RegisterInfos_mips.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterInfos_mips.h; path = Utility/RegisterInfos_mips.h; sourceTree = "<group>"; };
9A19A6A51163BB7E00E0D453 /* SBValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBValue.h; path = include/lldb/API/SBValue.h; sourceTree = "<group>"; };
9A19A6AD1163BB9800E0D453 /* SBValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBValue.cpp; path = source/API/SBValue.cpp; sourceTree = "<group>"; };
+ 9A1E59521EB2B0B9002206A5 /* SBTrace.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTrace.cpp; path = source/API/SBTrace.cpp; sourceTree = "<group>"; };
+ 9A1E59531EB2B0B9002206A5 /* SBTraceOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBTraceOptions.cpp; path = source/API/SBTraceOptions.cpp; sourceTree = "<group>"; };
+ 9A1E59581EB2B10D002206A5 /* SBTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBTrace.h; path = include/lldb/API/SBTrace.h; sourceTree = "<group>"; };
+ 9A1E59591EB2B10D002206A5 /* SBTraceOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBTraceOptions.h; path = include/lldb/API/SBTraceOptions.h; sourceTree = "<group>"; };
9A22A15D135E30370024DDC3 /* EmulateInstructionARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulateInstructionARM.cpp; sourceTree = "<group>"; };
9A22A15E135E30370024DDC3 /* EmulateInstructionARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmulateInstructionARM.h; sourceTree = "<group>"; };
9A22A15F135E30370024DDC3 /* EmulationStateARM.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EmulationStateARM.cpp; sourceTree = "<group>"; };
@@ -3051,6 +3058,7 @@
B2B7CCED15D1BFB700EEFB57 /* WatchpointOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WatchpointOptions.h; path = include/lldb/Breakpoint/WatchpointOptions.h; sourceTree = "<group>"; };
B2B7CCEF15D1C20F00EEFB57 /* WatchpointOptions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WatchpointOptions.cpp; path = source/Breakpoint/WatchpointOptions.cpp; sourceTree = "<group>"; };
B2D3033612EFA5C500F84EB3 /* InstructionUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InstructionUtils.h; path = Utility/InstructionUtils.h; sourceTree = "<group>"; };
+ D67521351EA17C3900439694 /* MainLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MainLoop.cpp; sourceTree = "<group>"; };
E73A15A41B548EC500786197 /* GDBRemoteSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GDBRemoteSignals.cpp; path = Utility/GDBRemoteSignals.cpp; sourceTree = "<group>"; };
E73A15A51B548EC500786197 /* GDBRemoteSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GDBRemoteSignals.h; path = Utility/GDBRemoteSignals.h; sourceTree = "<group>"; };
E769331D1A94D18100C73337 /* lldb-server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "lldb-server.cpp"; path = "tools/lldb-server/lldb-server.cpp"; sourceTree = "<group>"; };
@@ -4004,6 +4012,10 @@
8CCB017F19BA4DD00009FD44 /* SBThreadCollection.cpp */,
4C56543419D2297A002E9C44 /* SBThreadPlan.h */,
4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */,
+ 9A1E59581EB2B10D002206A5 /* SBTrace.h */,
+ 9A1E59521EB2B0B9002206A5 /* SBTrace.cpp */,
+ 9A1E59591EB2B10D002206A5 /* SBTraceOptions.h */,
+ 9A1E59531EB2B0B9002206A5 /* SBTraceOptions.cpp */,
2617447911685869005ADD65 /* SBType.h */,
261744771168585B005ADD65 /* SBType.cpp */,
9475C18514E5E9C5001BFC6D /* SBTypeCategory.h */,
@@ -5667,7 +5679,6 @@
children = (
2579065E1BD0488D00178368 /* DomainSocket.cpp */,
255EFF751AFABA950069F277 /* LockFilePosix.cpp */,
- 30DED5DC1B4ECB17004CC508 /* MainLoopPosix.cpp */,
AFDFDFD019E34D3400EAE509 /* ConnectionFileDescriptorPosix.cpp */,
3FDFDDC5199D37ED009756A7 /* FileSystem.cpp */,
3FDFE53019A292F0009756A7 /* HostInfoPosix.cpp */,
@@ -5902,6 +5913,7 @@
69A01E1A1236C5D400C660B5 /* common */ = {
isa = PBXGroup;
children = (
+ D67521351EA17C3900439694 /* MainLoop.cpp */,
2579065A1BD0488100178368 /* TCPSocket.cpp */,
2579065B1BD0488100178368 /* UDPSocket.cpp */,
255EFF731AFABA720069F277 /* LockFileBase.cpp */,
@@ -6419,6 +6431,7 @@
254FBBA31A9166F100BD6378 /* SBAttachInfo.h in Headers */,
26680221115FD13D008E1FE4 /* SBDefines.h in Headers */,
8CCB018219BA4E270009FD44 /* SBThreadCollection.h in Headers */,
+ 9A36D24D1EB3BE7F00AAD9EA /* SBTrace.h in Headers */,
AF0EBBEC185941360059E52F /* SBQueue.h in Headers */,
26680222115FD13D008E1FE4 /* SBError.h in Headers */,
26680223115FD13D008E1FE4 /* SBEvent.h in Headers */,
@@ -6457,6 +6470,7 @@
941BCC8014E48C4000BB969C /* SBTypeFormat.h in Headers */,
9475C18F14E5F858001BFC6D /* SBTypeNameSpecifier.h in Headers */,
941BCC8114E48C4000BB969C /* SBTypeSummary.h in Headers */,
+ 9A36D24E1EB3BE7F00AAD9EA /* SBTraceOptions.h in Headers */,
23059A121958B3B2007B8189 /* SBUnixSignals.h in Headers */,
941BCC8214E48C4000BB969C /* SBTypeSynthetic.h in Headers */,
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */,
@@ -7022,6 +7036,7 @@
23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */,
26680330116005E7008E1FE4 /* SBDebugger.cpp in Sources */,
26680331116005E9008E1FE4 /* SBCommunication.cpp in Sources */,
+ 9A1E595D1EB2B141002206A5 /* SBTraceOptions.cpp in Sources */,
26680332116005EA008E1FE4 /* SBCommandReturnObject.cpp in Sources */,
26680333116005EC008E1FE4 /* SBCommandInterpreter.cpp in Sources */,
26680335116005EE008E1FE4 /* SBBroadcaster.cpp in Sources */,
@@ -7042,6 +7057,7 @@
261744781168585B005ADD65 /* SBType.cpp in Sources */,
9A35758E116CFE0F00E8ED2F /* SBValueList.cpp in Sources */,
9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */,
+ 9A1E595C1EB2B141002206A5 /* SBTrace.cpp in Sources */,
9A3576AA116E9AC700E8ED2F /* SBHostOS.cpp in Sources */,
9AC703AF117675410086C050 /* SBInstruction.cpp in Sources */,
9AC703B1117675490086C050 /* SBInstructionList.cpp in Sources */,
@@ -7292,6 +7308,7 @@
945261C41B9A11FC00BF138D /* LibCxxUnorderedMap.cpp in Sources */,
26CEB5F218762056008F575A /* CommandObjectGUI.cpp in Sources */,
AF3A4AD21EA05C4700B5DEB4 /* PlatformRemoteDarwinDevice.cpp in Sources */,
+ D67521381EA17C4200439694 /* MainLoop.cpp in Sources */,
2689008013353E2200698AC0 /* CommandInterpreter.cpp in Sources */,
AF77E0A41A033D360096C0EA /* RegisterContextPOSIX_powerpc.cpp in Sources */,
4CDB8D6D1DBA91B6006C5B13 /* LibStdcppUniquePointer.cpp in Sources */,
@@ -7784,7 +7801,6 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 30DED5DE1B4ECB49004CC508 /* MainLoopPosix.cpp in Sources */,
E769331C1A94D15400C73337 /* lldb-gdbserver.cpp in Sources */,
26DC6A1D1337FECA00FF7998 /* lldb-platform.cpp in Sources */,
E769331E1A94D18100C73337 /* lldb-server.cpp in Sources */,
diff --git a/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py b/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py
index 61a67dc13987..edc83bf58985 100644
--- a/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py
+++ b/packages/Python/lldbsuite/test/lang/c/shared_lib/TestSharedLib.py
@@ -13,14 +13,13 @@ class SharedLibTestCase(TestBase):
mydir = TestBase.compute_mydir(__file__)
- def test_expr(self):
- """Test that types work when defined in a shared library and forward-declared in the main executable"""
+ def common_test_expr(self, preload_symbols):
if "clang" in self.getCompiler() and "3.4" in self.getCompilerVersion():
self.skipTest(
"llvm.org/pr16214 -- clang emits partial DWARF for structures referenced via typedef")
self.build()
- self.common_setup()
+ self.common_setup(preload_symbols)
# This should display correctly.
self.expect(
@@ -31,6 +30,18 @@ class SharedLibTestCase(TestBase):
"(sub_foo)",
"other_element = 3"])
+ self.expect(
+ "expression GetMeASubFoo(my_foo_ptr)",
+ startstr="(sub_foo *) $")
+
+ def test_expr(self):
+ """Test that types work when defined in a shared library and forward-declared in the main executable"""
+ self.common_test_expr(True)
+
+ def test_expr_no_preload(self):
+ """Test that types work when defined in a shared library and forward-declared in the main executable, but with preloading disabled"""
+ self.common_test_expr(False)
+
@unittest2.expectedFailure("rdar://problem/10704639")
def test_frame_variable(self):
"""Test that types work when defined in a shared library and forward-declared in the main executable"""
@@ -54,7 +65,7 @@ class SharedLibTestCase(TestBase):
self.line = line_number(self.source, '// Set breakpoint 0 here.')
self.shlib_names = ["foo"]
- def common_setup(self):
+ def common_setup(self, preload_symbols = True):
# Run in synchronous mode
self.dbg.SetAsync(False)
@@ -62,6 +73,8 @@ class SharedLibTestCase(TestBase):
target = self.dbg.CreateTarget("a.out")
self.assertTrue(target, VALID_TARGET)
+ self.runCmd("settings set target.preload-symbols " + str(preload_symbols).lower())
+
# Break inside the foo function which takes a bar_ptr argument.
lldbutil.run_break_set_by_file_and_line(
self, self.source, self.line, num_expected_locations=1, loc_exact=True)
diff --git a/packages/Python/lldbsuite/test/make/Android.rules b/packages/Python/lldbsuite/test/make/Android.rules
index 3e6a093f4bae..058401f425ad 100644
--- a/packages/Python/lldbsuite/test/make/Android.rules
+++ b/packages/Python/lldbsuite/test/make/Android.rules
@@ -63,6 +63,7 @@ endif
GCC_TOOLCHAIN = $(NDK_ROOT)/toolchains/$(TOOLCHAIN_DIR)/prebuilt/$(HOST_TAG)
OBJCOPY ?= $(GCC_TOOLCHAIN)/bin/$(TOOL_PREFIX)-objcopy
+ARCHIVER ?= $(GCC_TOOLCHAIN)/bin/$(TOOL_PREFIX)-ar
ifeq "$(findstring clang,$(CC))" "clang"
ARCH_CFLAGS += -target $(TRIPLE) -gcc-toolchain $(GCC_TOOLCHAIN)
diff --git a/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py b/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
index b4e90c71721c..4e03d557b7a9 100644
--- a/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
+++ b/packages/Python/lldbsuite/test/tools/lldb-mi/control/TestMiExec.py
@@ -319,8 +319,16 @@ class MiExecTestCase(lldbmi_testcase.MiTestCaseBase):
# -exec-step can keep us in the g_MyFunction for gcc
self.runCmd("-exec-finish --frame 0")
self.expect("\^running")
- self.expect(
- "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"")
+ it = self.expect(["\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"",
+ "\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"29\""])
+
+ if it == 1:
+ # Call to s_MyFunction may not follow immediately after g_MyFunction.
+ # There might be some instructions in between to restore caller-saved registers.
+ # We need to get past these instructions with a next to reach call to s_MyFunction.
+ self.runCmd("-exec-next --thread 1")
+ self.expect("\^running")
+ self.expect("\*stopped,reason=\"end-stepping-range\".+?main\.cpp\",line=\"30\"")
# Test that -exec-step steps into s_MyFunction
# (and that --frame is optional)
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index ddc9fca80671..d168474c3479 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -1432,6 +1432,22 @@ size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
return sc_list.GetSize() - initial_size;
}
+void Module::PreloadSymbols() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ SymbolVendor * sym_vendor = GetSymbolVendor();
+ if (!sym_vendor) {
+ return;
+ }
+ // Prime the symbol file first, since it adds symbols to the symbol table.
+ if (SymbolFile *symbol_file = sym_vendor->GetSymbolFile()) {
+ symbol_file->PreloadSymbols();
+ }
+ // Now we can prime the symbol table.
+ if (Symtab * symtab = sym_vendor->GetSymtab()) {
+ symtab->PreloadSymbols();
+ }
+}
+
void Module::SetSymbolFileFileSpec(const FileSpec &file) {
if (!file.Exists())
return;
diff --git a/source/Host/CMakeLists.txt b/source/Host/CMakeLists.txt
index f00d67420fa3..2a73c30f8524 100644
--- a/source/Host/CMakeLists.txt
+++ b/source/Host/CMakeLists.txt
@@ -15,6 +15,7 @@ add_host_subdirectory(common
common/HostThread.cpp
common/IOObject.cpp
common/LockFileBase.cpp
+ common/MainLoop.cpp
common/MonitoringProcessLauncher.cpp
common/NativeBreakpoint.cpp
common/NativeBreakpointList.cpp
@@ -85,7 +86,6 @@ else()
posix/HostProcessPosix.cpp
posix/HostThreadPosix.cpp
posix/LockFilePosix.cpp
- posix/MainLoopPosix.cpp
posix/PipePosix.cpp
posix/ProcessLauncherPosixFork.cpp
)
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
new file mode 100644
index 000000000000..8a9d4f020d5f
--- /dev/null
+++ b/source/Host/common/MainLoop.cpp
@@ -0,0 +1,382 @@
+//===-- MainLoop.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Config/llvm-config.h"
+
+#include "lldb/Host/MainLoop.h"
+#include "lldb/Utility/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cerrno>
+#include <csignal>
+#include <vector>
+#include <time.h>
+
+#if HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#elif defined(LLVM_ON_WIN32)
+#include <winsock2.h>
+#else
+#include <poll.h>
+#endif
+
+#ifdef LLVM_ON_WIN32
+#define POLL WSAPoll
+#else
+#define POLL poll
+#endif
+
+#ifdef __ANDROID__
+#define FORCE_PSELECT
+#endif
+
+#if SIGNAL_POLLING_UNSUPPORTED
+#ifdef LLVM_ON_WIN32
+typedef int sigset_t;
+typedef int siginfo_t;
+#endif
+
+int ppoll(struct pollfd *fds, size_t nfds, const struct timespec *timeout_ts,
+ const sigset_t *) {
+ int timeout =
+ (timeout_ts == nullptr)
+ ? -1
+ : (timeout_ts->tv_sec * 1000 + timeout_ts->tv_nsec / 1000000);
+ return POLL(fds, nfds, timeout);
+}
+
+#endif
+
+using namespace lldb;
+using namespace lldb_private;
+
+static sig_atomic_t g_signal_flags[NSIG];
+
+static void SignalHandler(int signo, siginfo_t *info, void *) {
+ assert(signo < NSIG);
+ g_signal_flags[signo] = 1;
+}
+
+class MainLoop::RunImpl {
+public:
+ // TODO: Use llvm::Expected<T>
+ static std::unique_ptr<RunImpl> Create(MainLoop &loop, Error &error);
+ ~RunImpl();
+
+ Error Poll();
+
+ template <typename F> void ForEachReadFD(F &&f);
+ template <typename F> void ForEachSignal(F &&f);
+
+private:
+ MainLoop &loop;
+
+#if HAVE_SYS_EVENT_H
+ int queue_id;
+ std::vector<struct kevent> in_events;
+ struct kevent out_events[4];
+ int num_events = -1;
+
+ RunImpl(MainLoop &loop, int queue_id) : loop(loop), queue_id(queue_id) {
+ in_events.reserve(loop.m_read_fds.size() + loop.m_signals.size());
+ }
+#else
+ std::vector<int> signals;
+#ifdef FORCE_PSELECT
+ fd_set read_fd_set;
+#else
+ std::vector<struct pollfd> read_fds;
+#endif
+
+ RunImpl(MainLoop &loop) : loop(loop) {
+ signals.reserve(loop.m_signals.size());
+ }
+
+ sigset_t get_sigmask();
+#endif
+};
+
+#if HAVE_SYS_EVENT_H
+MainLoop::RunImpl::~RunImpl() {
+ int r = close(queue_id);
+ assert(r == 0);
+ (void)r;
+}
+std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
+{
+ error.Clear();
+ int queue_id = kqueue();
+ if(queue_id < 0) {
+ error = Error(errno, eErrorTypePOSIX);
+ return nullptr;
+ }
+ return std::unique_ptr<RunImpl>(new RunImpl(loop, queue_id));
+}
+
+Error MainLoop::RunImpl::Poll() {
+ in_events.resize(loop.m_read_fds.size() + loop.m_signals.size());
+ unsigned i = 0;
+ for (auto &fd : loop.m_read_fds)
+ EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
+
+ for (const auto &sig : loop.m_signals)
+ EV_SET(&in_events[i++], sig.first, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
+
+ num_events = kevent(queue_id, in_events.data(), in_events.size(), out_events,
+ llvm::array_lengthof(out_events), nullptr);
+
+ if (num_events < 0)
+ return Error("kevent() failed with error %d\n", num_events);
+ return Error();
+}
+
+template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+ assert(num_events >= 0);
+ for (int i = 0; i < num_events; ++i) {
+ f(out_events[i].ident);
+ if (loop.m_terminate_request)
+ return;
+ }
+}
+template <typename F> void MainLoop::RunImpl::ForEachSignal(F && f) {}
+#else
+MainLoop::RunImpl::~RunImpl() {}
+std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
+{
+ error.Clear();
+ return std::unique_ptr<RunImpl>(new RunImpl(loop));
+}
+
+sigset_t MainLoop::RunImpl::get_sigmask() {
+#if SIGNAL_POLLING_UNSUPPORTED
+ return 0;
+#else
+ sigset_t sigmask;
+ int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask);
+ assert(ret == 0);
+ (void) ret;
+
+ for (const auto &sig : loop.m_signals) {
+ signals.push_back(sig.first);
+ sigdelset(&sigmask, sig.first);
+ }
+ return sigmask;
+#endif
+}
+
+#ifdef FORCE_PSELECT
+Error MainLoop::RunImpl::Poll() {
+ signals.clear();
+
+ FD_ZERO(&read_fd_set);
+ int nfds = 0;
+ for (const auto &fd : loop.m_read_fds) {
+ FD_SET(fd.first, &read_fd_set);
+ nfds = std::max(nfds, fd.first + 1);
+ }
+
+ sigset_t sigmask = get_sigmask();
+ if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) == -1 &&
+ errno != EINTR)
+ return Error(errno, eErrorTypePOSIX);
+
+ return Error();
+}
+
+template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+ for (const auto &fd : loop.m_read_fds) {
+ if(!FD_ISSET(fd.first, &read_fd_set))
+ continue;
+
+ f(fd.first);
+ if (loop.m_terminate_request)
+ return;
+ }
+}
+#else
+Error MainLoop::RunImpl::Poll() {
+ signals.clear();
+ read_fds.clear();
+
+ sigset_t sigmask = get_sigmask();
+
+ for (const auto &fd : loop.m_read_fds) {
+ struct pollfd pfd;
+ pfd.fd = fd.first;
+ pfd.events = POLLIN;
+ pfd.revents = 0;
+ read_fds.push_back(pfd);
+ }
+
+ if (ppoll(read_fds.data(), read_fds.size(), nullptr, &sigmask) == -1 &&
+ errno != EINTR)
+ return Error(errno, eErrorTypePOSIX);
+
+ return Error();
+}
+
+template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+ for (const auto &fd : read_fds) {
+ if ((fd.revents & POLLIN) == 0)
+ continue;
+
+ f(fd.fd);
+ if (loop.m_terminate_request)
+ return;
+ }
+}
+#endif
+
+template <typename F> void MainLoop::RunImpl::ForEachSignal(F &&f) {
+ for (int sig : signals) {
+ if (g_signal_flags[sig] == 0)
+ continue; // No signal
+ g_signal_flags[sig] = 0;
+ f(sig);
+
+ if (loop.m_terminate_request)
+ return;
+ }
+}
+#endif
+
+MainLoop::~MainLoop() {
+ assert(m_read_fds.size() == 0);
+ assert(m_signals.size() == 0);
+}
+
+MainLoop::ReadHandleUP
+MainLoop::RegisterReadObject(const IOObjectSP &object_sp,
+ const Callback &callback, Error &error) {
+#ifdef LLVM_ON_WIN32
+ if (object_sp->GetFdType() != IOObject:: eFDTypeSocket) {
+ error.SetErrorString("MainLoop: non-socket types unsupported on Windows");
+ return nullptr;
+ }
+#endif
+ if (!object_sp || !object_sp->IsValid()) {
+ error.SetErrorString("IO object is not valid.");
+ return nullptr;
+ }
+
+ const bool inserted =
+ m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
+ if (!inserted) {
+ error.SetErrorStringWithFormat("File descriptor %d already monitored.",
+ object_sp->GetWaitableHandle());
+ return nullptr;
+ }
+
+ return CreateReadHandle(object_sp);
+}
+
+// We shall block the signal, then install the signal handler. The signal will
+// be unblocked in
+// the Run() function to check for signal delivery.
+MainLoop::SignalHandleUP
+MainLoop::RegisterSignal(int signo, const Callback &callback,
+ Error &error) {
+#ifdef SIGNAL_POLLING_UNSUPPORTED
+ error.SetErrorString("Signal polling is not supported on this platform.");
+ return nullptr;
+#else
+ if (m_signals.find(signo) != m_signals.end()) {
+ error.SetErrorStringWithFormat("Signal %d already monitored.", signo);
+ return nullptr;
+ }
+
+ SignalInfo info;
+ info.callback = callback;
+ struct sigaction new_action;
+ new_action.sa_sigaction = &SignalHandler;
+ new_action.sa_flags = SA_SIGINFO;
+ sigemptyset(&new_action.sa_mask);
+ sigaddset(&new_action.sa_mask, signo);
+
+ sigset_t old_set;
+ if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) {
+ error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n",
+ ret);
+ return nullptr;
+ }
+
+ info.was_blocked = sigismember(&old_set, signo);
+ if (sigaction(signo, &new_action, &info.old_action) == -1) {
+ error.SetErrorToErrno();
+ if (!info.was_blocked)
+ pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr);
+ return nullptr;
+ }
+
+ m_signals.insert({signo, info});
+ g_signal_flags[signo] = 0;
+
+ return SignalHandleUP(new SignalHandle(*this, signo));
+#endif
+}
+
+void MainLoop::UnregisterReadObject(IOObject::WaitableHandle handle) {
+ bool erased = m_read_fds.erase(handle);
+ UNUSED_IF_ASSERT_DISABLED(erased);
+ assert(erased);
+}
+
+void MainLoop::UnregisterSignal(int signo) {
+#if SIGNAL_POLLING_UNSUPPORTED
+ Error("Signal polling is not supported on this platform.");
+#else
+ // We undo the actions of RegisterSignal on a best-effort basis.
+ auto it = m_signals.find(signo);
+ assert(it != m_signals.end());
+
+ sigaction(signo, &it->second.old_action, nullptr);
+
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, signo);
+ pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set,
+ nullptr);
+
+ m_signals.erase(it);
+#endif
+}
+
+Error MainLoop::Run() {
+ m_terminate_request = false;
+
+ Error error;
+ auto impl = RunImpl::Create(*this, error);
+ if (!impl)
+ return error;
+
+ // run until termination or until we run out of things to listen to
+ while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
+
+ error = impl->Poll();
+ if (error.Fail())
+ return error;
+
+ impl->ForEachSignal([&](int sig) {
+ auto it = m_signals.find(sig);
+ if (it != m_signals.end())
+ it->second.callback(*this); // Do the work
+ });
+ if (m_terminate_request)
+ return Error();
+
+ impl->ForEachReadFD([&](int fd) {
+ auto it = m_read_fds.find(fd);
+ if (it != m_read_fds.end())
+ it->second(*this); // Do the work
+ });
+ if (m_terminate_request)
+ return Error();
+ }
+ return Error();
+}
diff --git a/source/Host/common/Socket.cpp b/source/Host/common/Socket.cpp
index 2a665ddacb64..d73b5d0ad073 100644
--- a/source/Host/common/Socket.cpp
+++ b/source/Host/common/Socket.cpp
@@ -18,6 +18,8 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
+#include "llvm/ADT/STLExtras.h"
+
#ifndef LLDB_DISABLE_POSIX
#include "lldb/Host/posix/DomainSocket.h"
@@ -67,9 +69,11 @@ bool IsInterrupted() {
}
}
-Socket::Socket(NativeSocket socket, SocketProtocol protocol, bool should_close)
+Socket::Socket(SocketProtocol protocol, bool should_close,
+ bool child_processes_inherit)
: IOObject(eFDTypeSocket, should_close), m_protocol(protocol),
- m_socket(socket) {}
+ m_socket(kInvalidSocketValue),
+ m_child_processes_inherit(child_processes_inherit) {}
Socket::~Socket() { Close(); }
@@ -81,14 +85,17 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
std::unique_ptr<Socket> socket_up;
switch (protocol) {
case ProtocolTcp:
- socket_up.reset(new TCPSocket(child_processes_inherit, error));
+ socket_up =
+ llvm::make_unique<TCPSocket>(true, child_processes_inherit);
break;
case ProtocolUdp:
- socket_up.reset(new UDPSocket(child_processes_inherit, error));
+ socket_up =
+ llvm::make_unique<UDPSocket>(true, child_processes_inherit);
break;
case ProtocolUnixDomain:
#ifndef LLDB_DISABLE_POSIX
- socket_up.reset(new DomainSocket(child_processes_inherit, error));
+ socket_up =
+ llvm::make_unique<DomainSocket>(true, child_processes_inherit);
#else
error.SetErrorString(
"Unix domain sockets are not supported on this platform.");
@@ -96,7 +103,8 @@ std::unique_ptr<Socket> Socket::Create(const SocketProtocol protocol,
break;
case ProtocolUnixAbstract:
#ifdef __linux__
- socket_up.reset(new AbstractSocket(child_processes_inherit, error));
+ socket_up =
+ llvm::make_unique<AbstractSocket>(child_processes_inherit);
#else
error.SetErrorString(
"Abstract domain sockets are not supported on this platform.");
@@ -145,7 +153,7 @@ Error Socket::TcpListen(llvm::StringRef host_and_port,
return error;
std::unique_ptr<TCPSocket> listen_socket(
- new TCPSocket(child_processes_inherit, error));
+ new TCPSocket(true, child_processes_inherit));
if (error.Fail())
return error;
@@ -208,7 +216,7 @@ Error Socket::UnixDomainAccept(llvm::StringRef name,
if (error.Fail())
return error;
- error = listen_socket->Accept(name, child_processes_inherit, socket);
+ error = listen_socket->Accept(socket);
return error;
}
@@ -240,18 +248,22 @@ Error Socket::UnixAbstractAccept(llvm::StringRef name,
if (error.Fail())
return error;
- error = listen_socket->Accept(name, child_processes_inherit, socket);
+ error = listen_socket->Accept(socket);
return error;
}
bool Socket::DecodeHostAndPort(llvm::StringRef host_and_port,
std::string &host_str, std::string &port_str,
int32_t &port, Error *error_ptr) {
- static RegularExpression g_regex(llvm::StringRef("([^:]+):([0-9]+)"));
+ static RegularExpression g_regex(
+ llvm::StringRef("([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)"));
RegularExpression::Match regex_match(2);
if (g_regex.Execute(host_and_port, &regex_match)) {
if (regex_match.GetMatchAtIndex(host_and_port.data(), 1, host_str) &&
regex_match.GetMatchAtIndex(host_and_port.data(), 2, port_str)) {
+ // IPv6 addresses are wrapped in [] when specified with ports
+ if (host_str.front() == '[' && host_str.back() == ']')
+ host_str = host_str.substr(1, host_str.size() - 2);
bool ok = false;
port = StringConvert::ToUInt32(port_str.c_str(), UINT32_MAX, 10, &ok);
if (ok && port <= UINT16_MAX) {
@@ -404,12 +416,12 @@ NativeSocket Socket::CreateSocket(const int domain, const int type,
const int protocol,
bool child_processes_inherit, Error &error) {
error.Clear();
- auto socketType = type;
+ auto socket_type = type;
#ifdef SOCK_CLOEXEC
if (!child_processes_inherit)
- socketType |= SOCK_CLOEXEC;
+ socket_type |= SOCK_CLOEXEC;
#endif
- auto sock = ::socket(domain, socketType, protocol);
+ auto sock = ::socket(domain, socket_type, protocol);
if (sock == kInvalidSocketValue)
SetLastError(error);
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index b41cef6ca2eb..440ae5d9027f 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -6,6 +6,12 @@
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
+//
+// Note: This file is used on Darwin by debugserver, so it needs to remain as
+// self contained as possible, and devoid of references to LLVM unless
+// there is compelling reason.
+//
+//===----------------------------------------------------------------------===//
#if defined(_MSC_VER)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
@@ -227,7 +233,8 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service,
int ai_flags) {
Clear();
- auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype, ai_protocol, ai_flags);
+ auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype,
+ ai_protocol, ai_flags);
if (!addresses.empty())
*this = addresses[0];
return IsValid();
diff --git a/source/Host/common/TCPSocket.cpp b/source/Host/common/TCPSocket.cpp
index 9a009280a904..55db4bb0c456 100644
--- a/source/Host/common/TCPSocket.cpp
+++ b/source/Host/common/TCPSocket.cpp
@@ -14,30 +14,57 @@
#include "lldb/Host/common/TCPSocket.h"
#include "lldb/Host/Config.h"
+#include "lldb/Host/MainLoop.h"
#include "lldb/Utility/Log.h"
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/raw_ostream.h"
+
#ifndef LLDB_DISABLE_POSIX
#include <arpa/inet.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#endif
+#if defined(LLVM_ON_WIN32)
+#include <winsock2.h>
+#endif
+
+#ifdef LLVM_ON_WIN32
+#define CLOSE_SOCKET closesocket
+typedef const char *set_socket_option_arg_type;
+#else
+#define CLOSE_SOCKET ::close
+typedef const void *set_socket_option_arg_type;
+#endif
+
using namespace lldb;
using namespace lldb_private;
namespace {
-
-const int kDomain = AF_INET;
const int kType = SOCK_STREAM;
}
-TCPSocket::TCPSocket(NativeSocket socket, bool should_close)
- : Socket(socket, ProtocolTcp, should_close) {}
+TCPSocket::TCPSocket(bool should_close, bool child_processes_inherit)
+ : Socket(ProtocolTcp, should_close, child_processes_inherit) {}
-TCPSocket::TCPSocket(bool child_processes_inherit, Error &error)
- : TCPSocket(CreateSocket(kDomain, kType, IPPROTO_TCP,
- child_processes_inherit, error),
- true) {}
+TCPSocket::TCPSocket(NativeSocket socket, const TCPSocket &listen_socket)
+ : Socket(ProtocolTcp, listen_socket.m_should_close_fd,
+ listen_socket.m_child_processes_inherit) {
+ m_socket = socket;
+}
+
+TCPSocket::TCPSocket(NativeSocket socket, bool should_close,
+ bool child_processes_inherit)
+ : Socket(ProtocolTcp, should_close, child_processes_inherit) {
+ m_socket = socket;
+}
+
+TCPSocket::~TCPSocket() { CloseListenSockets(); }
+
+bool TCPSocket::IsValid() const {
+ return m_socket != kInvalidSocketValue || m_listen_sockets.size() != 0;
+}
// Return the port number that is being used by the socket.
uint16_t TCPSocket::GetLocalPortNumber() const {
@@ -46,6 +73,12 @@ uint16_t TCPSocket::GetLocalPortNumber() const {
socklen_t sock_addr_len = sock_addr.GetMaxLength();
if (::getsockname(m_socket, sock_addr, &sock_addr_len) == 0)
return sock_addr.GetPort();
+ } else if (!m_listen_sockets.empty()) {
+ SocketAddress sock_addr;
+ socklen_t sock_addr_len = sock_addr.GetMaxLength();
+ if (::getsockname(m_listen_sockets.begin()->first, sock_addr,
+ &sock_addr_len) == 0)
+ return sock_addr.GetPort();
}
return 0;
}
@@ -84,9 +117,18 @@ std::string TCPSocket::GetRemoteIPAddress() const {
return "";
}
+Error TCPSocket::CreateSocket(int domain) {
+ Error error;
+ if (IsValid())
+ error = Close();
+ if (error.Fail())
+ return error;
+ m_socket = Socket::CreateSocket(domain, kType, IPPROTO_TCP,
+ m_child_processes_inherit, error);
+ return error;
+}
+
Error TCPSocket::Connect(llvm::StringRef name) {
- if (m_socket == kInvalidSocketValue)
- return Error("Invalid socket");
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
if (log)
@@ -99,146 +141,140 @@ Error TCPSocket::Connect(llvm::StringRef name) {
if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
return error;
- struct sockaddr_in sa;
- ::memset(&sa, 0, sizeof(sa));
- sa.sin_family = kDomain;
- sa.sin_port = htons(port);
-
- int inet_pton_result = ::inet_pton(kDomain, host_str.c_str(), &sa.sin_addr);
-
- if (inet_pton_result <= 0) {
- struct hostent *host_entry = gethostbyname(host_str.c_str());
- if (host_entry)
- host_str = ::inet_ntoa(*(struct in_addr *)*host_entry->h_addr_list);
- inet_pton_result = ::inet_pton(kDomain, host_str.c_str(), &sa.sin_addr);
- if (inet_pton_result <= 0) {
- if (inet_pton_result == -1)
- SetLastError(error);
- else
- error.SetErrorStringWithFormat("invalid host string: '%s'",
- host_str.c_str());
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ host_str.c_str(), NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ for (auto address : addresses) {
+ error = CreateSocket(address.GetFamily());
+ if (error.Fail())
+ continue;
- return error;
+ address.SetPort(port);
+
+ if (-1 == ::connect(GetNativeSocket(), &address.sockaddr(),
+ address.GetLength())) {
+ CLOSE_SOCKET(GetNativeSocket());
+ continue;
}
- }
- if (-1 ==
- ::connect(GetNativeSocket(), (const struct sockaddr *)&sa, sizeof(sa))) {
- SetLastError(error);
+ SetOptionNoDelay();
+
+ error.Clear();
return error;
}
- // Keep our TCP packets coming without any delays.
- SetOptionNoDelay();
- error.Clear();
+ error.SetErrorString("Failed to connect port");
return error;
}
Error TCPSocket::Listen(llvm::StringRef name, int backlog) {
- Error error;
-
- // enable local address reuse
- SetOptionReuseAddress();
-
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf("TCPSocket::%s (%s)", __FUNCTION__, name.data());
+ Error error;
std::string host_str;
std::string port_str;
int32_t port = INT32_MIN;
if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
return error;
- SocketAddress bind_addr;
+ if (host_str == "*")
+ host_str = "0.0.0.0";
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ host_str.c_str(), NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ for (auto address : addresses) {
+ int fd = Socket::CreateSocket(address.GetFamily(), kType, IPPROTO_TCP,
+ m_child_processes_inherit, error);
+ if (error.Fail()) {
+ error.Clear();
+ continue;
+ }
- // Only bind to the loopback address if we are expecting a connection from
- // localhost to avoid any firewall issues.
- const bool bind_addr_success = (host_str == "127.0.0.1")
- ? bind_addr.SetToLocalhost(kDomain, port)
- : bind_addr.SetToAnyAddress(kDomain, port);
+ // enable local address reuse
+ int option_value = 1;
+ set_socket_option_arg_type option_value_p =
+ reinterpret_cast<set_socket_option_arg_type>(&option_value);
+ ::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, option_value_p,
+ sizeof(option_value));
- if (!bind_addr_success) {
- error.SetErrorString("Failed to bind port");
- return error;
- }
+ address.SetPort(port);
+
+ int err = ::bind(fd, &address.sockaddr(), address.GetLength());
+ if (-1 != err)
+ err = ::listen(fd, backlog);
- int err = ::bind(GetNativeSocket(), bind_addr, bind_addr.GetLength());
- if (err != -1)
- err = ::listen(GetNativeSocket(), backlog);
+ if (-1 == err) {
+ CLOSE_SOCKET(fd);
+ continue;
+ }
- if (err == -1)
- SetLastError(error);
+ if (port == 0) {
+ socklen_t sa_len = address.GetLength();
+ if (getsockname(fd, &address.sockaddr(), &sa_len) == 0)
+ port = address.GetPort();
+ }
+ m_listen_sockets[fd] = address;
+ }
+ if (m_listen_sockets.size() == 0)
+ error.SetErrorString("Failed to connect port");
return error;
}
-Error TCPSocket::Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&conn_socket) {
+void TCPSocket::CloseListenSockets() {
+ for (auto socket : m_listen_sockets)
+ CLOSE_SOCKET(socket.first);
+ m_listen_sockets.clear();
+}
+
+Error TCPSocket::Accept(Socket *&conn_socket) {
Error error;
- std::string host_str;
- std::string port_str;
- int32_t port;
- if (!DecodeHostAndPort(name, host_str, port_str, port, &error))
+ if (m_listen_sockets.size() == 0) {
+ error.SetErrorString("No open listening sockets!");
return error;
+ }
- const sa_family_t family = kDomain;
- const int socktype = kType;
- const int protocol = IPPROTO_TCP;
- SocketAddress listen_addr;
- if (host_str.empty())
- listen_addr.SetToLocalhost(family, port);
- else if (host_str.compare("*") == 0)
- listen_addr.SetToAnyAddress(family, port);
- else {
- if (!listen_addr.getaddrinfo(host_str.c_str(), port_str.c_str(), family,
- socktype, protocol)) {
- error.SetErrorStringWithFormat("unable to resolve hostname '%s'",
- host_str.c_str());
+ int sock = -1;
+ int listen_sock = -1;
+ lldb_private::SocketAddress AcceptAddr;
+ MainLoop accept_loop;
+ std::vector<MainLoopBase::ReadHandleUP> handles;
+ for (auto socket : m_listen_sockets) {
+ auto fd = socket.first;
+ auto inherit = this->m_child_processes_inherit;
+ auto io_sp = IOObjectSP(new TCPSocket(socket.first, false, inherit));
+ handles.emplace_back(accept_loop.RegisterReadObject(
+ io_sp, [fd, inherit, &sock, &AcceptAddr, &error,
+ &listen_sock](MainLoopBase &loop) {
+ socklen_t sa_len = AcceptAddr.GetMaxLength();
+ sock = AcceptSocket(fd, &AcceptAddr.sockaddr(), &sa_len, inherit,
+ error);
+ listen_sock = fd;
+ loop.RequestTermination();
+ }, error));
+ if (error.Fail())
return error;
- }
}
bool accept_connection = false;
std::unique_ptr<TCPSocket> accepted_socket;
-
// Loop until we are happy with our connection
while (!accept_connection) {
- struct sockaddr_in accept_addr;
- ::memset(&accept_addr, 0, sizeof accept_addr);
-#if !(defined(__linux__) || defined(_WIN32))
- accept_addr.sin_len = sizeof accept_addr;
-#endif
- socklen_t accept_addr_len = sizeof accept_addr;
-
- int sock = AcceptSocket(GetNativeSocket(), (struct sockaddr *)&accept_addr,
- &accept_addr_len, child_processes_inherit, error);
-
+ accept_loop.Run();
+
if (error.Fail())
- break;
-
- bool is_same_addr = true;
-#if !(defined(__linux__) || (defined(_WIN32)))
- is_same_addr = (accept_addr_len == listen_addr.sockaddr_in().sin_len);
-#endif
- if (is_same_addr)
- is_same_addr = (accept_addr.sin_addr.s_addr ==
- listen_addr.sockaddr_in().sin_addr.s_addr);
-
- if (is_same_addr ||
- (listen_addr.sockaddr_in().sin_addr.s_addr == INADDR_ANY)) {
- accept_connection = true;
- accepted_socket.reset(new TCPSocket(sock, true));
- } else {
- const uint8_t *accept_ip = (const uint8_t *)&accept_addr.sin_addr.s_addr;
- const uint8_t *listen_ip =
- (const uint8_t *)&listen_addr.sockaddr_in().sin_addr.s_addr;
- ::fprintf(stderr, "error: rejecting incoming connection from %u.%u.%u.%u "
- "(expecting %u.%u.%u.%u)\n",
- accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
- listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
- accepted_socket.reset();
+ return error;
+
+ lldb_private::SocketAddress &AddrIn = m_listen_sockets[listen_sock];
+ if (!AddrIn.IsAnyAddr() && AcceptAddr != AddrIn) {
+ CLOSE_SOCKET(sock);
+ llvm::errs() << llvm::formatv(
+ "error: rejecting incoming connection from {0} (expecting {1})",
+ AcceptAddr.GetIPAddress(), AddrIn.GetIPAddress());
+ continue;
}
+ accept_connection = true;
+ accepted_socket.reset(new TCPSocket(sock, *this));
}
if (!accepted_socket)
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index 7ca62e7496ba..a32657aab0a6 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -28,13 +28,16 @@ const int kDomain = AF_INET;
const int kType = SOCK_DGRAM;
static const char *g_not_supported_error = "Not supported";
-}
+} // namespace
-UDPSocket::UDPSocket(NativeSocket socket) : Socket(socket, ProtocolUdp, true) {}
+UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit)
+ : Socket(ProtocolUdp, should_close, child_processes_inherit) {}
-UDPSocket::UDPSocket(bool child_processes_inherit, Error &error)
- : UDPSocket(
- CreateSocket(kDomain, kType, 0, child_processes_inherit, error)) {}
+UDPSocket::UDPSocket(NativeSocket socket, const UDPSocket &listen_socket)
+ : Socket(ProtocolUdp, listen_socket.m_should_close_fd,
+ listen_socket.m_child_processes_inherit) {
+ m_socket = socket;
+}
size_t UDPSocket::Send(const void *buf, const size_t num_bytes) {
return ::sendto(m_socket, static_cast<const char *>(buf), num_bytes, 0,
@@ -42,27 +45,14 @@ size_t UDPSocket::Send(const void *buf, const size_t num_bytes) {
}
Error UDPSocket::Connect(llvm::StringRef name) {
- return Error("%s", g_not_supported_error);
-}
-
-Error UDPSocket::Listen(llvm::StringRef name, int backlog) {
- return Error("%s", g_not_supported_error);
-}
-
-Error UDPSocket::Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) {
- return Error("%s", g_not_supported_error);
-}
-
-Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) {
- std::unique_ptr<UDPSocket> final_socket;
-
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
Error error;
+ if (error.Fail())
+ return error;
+
std::string host_str;
std::string port_str;
int32_t port = INT32_MIN;
@@ -94,12 +84,11 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
for (struct addrinfo *service_info_ptr = service_info_list;
service_info_ptr != nullptr;
service_info_ptr = service_info_ptr->ai_next) {
- auto send_fd = CreateSocket(
+ m_socket = Socket::CreateSocket(
service_info_ptr->ai_family, service_info_ptr->ai_socktype,
- service_info_ptr->ai_protocol, child_processes_inherit, error);
+ service_info_ptr->ai_protocol, m_child_processes_inherit, error);
if (error.Success()) {
- final_socket.reset(new UDPSocket(send_fd));
- final_socket->m_sockaddr = service_info_ptr;
+ m_sockaddr = service_info_ptr;
break;
} else
continue;
@@ -107,16 +96,17 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
::freeaddrinfo(service_info_list);
- if (!final_socket)
+ if (IsValid())
return error;
SocketAddress bind_addr;
// Only bind to the loopback address if we are expecting a connection from
// localhost to avoid any firewall issues.
- const bool bind_addr_success = (host_str == "127.0.0.1" || host_str == "localhost")
- ? bind_addr.SetToLocalhost(kDomain, port)
- : bind_addr.SetToAnyAddress(kDomain, port);
+ const bool bind_addr_success =
+ (host_str == "127.0.0.1" || host_str == "localhost")
+ ? bind_addr.SetToLocalhost(kDomain, port)
+ : bind_addr.SetToAnyAddress(kDomain, port);
if (!bind_addr_success) {
error.SetErrorString("Failed to get hostspec to bind for");
@@ -125,13 +115,37 @@ Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
bind_addr.SetPort(0); // Let the source port # be determined dynamically
- err = ::bind(final_socket->GetNativeSocket(), bind_addr, bind_addr.GetLength());
-
- struct sockaddr_in source_info;
- socklen_t address_len = sizeof (struct sockaddr_in);
- err = ::getsockname(final_socket->GetNativeSocket(), (struct sockaddr *) &source_info, &address_len);
+ err = ::bind(m_socket, bind_addr, bind_addr.GetLength());
- socket = final_socket.release();
error.Clear();
return error;
}
+
+Error UDPSocket::Listen(llvm::StringRef name, int backlog) {
+ return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Accept(Socket *&socket) {
+ return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::CreateSocket() {
+ Error error;
+ if (IsValid())
+ error = Close();
+ if (error.Fail())
+ return error;
+ m_socket =
+ Socket::CreateSocket(kDomain, kType, 0, m_child_processes_inherit, error);
+ return error;
+}
+
+Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
+ Socket *&socket) {
+ std::unique_ptr<UDPSocket> final_socket(
+ new UDPSocket(true, child_processes_inherit));
+ Error error = final_socket->Connect(name);
+ if (!error.Fail())
+ socket = final_socket.release();
+ return error;
+}
diff --git a/source/Host/linux/AbstractSocket.cpp b/source/Host/linux/AbstractSocket.cpp
index b6b59ae403db..2d6f6adaf1ef 100644
--- a/source/Host/linux/AbstractSocket.cpp
+++ b/source/Host/linux/AbstractSocket.cpp
@@ -14,8 +14,8 @@
using namespace lldb;
using namespace lldb_private;
-AbstractSocket::AbstractSocket(bool child_processes_inherit, Error &error)
- : DomainSocket(ProtocolUnixAbstract, child_processes_inherit, error) {}
+AbstractSocket::AbstractSocket(bool child_processes_inherit)
+ : DomainSocket(ProtocolUnixAbstract, child_processes_inherit) {}
size_t AbstractSocket::GetNameOffset() const { return 1; }
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index a3ac36558e32..befc847d8a86 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -218,7 +218,7 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
// assume we don't own it.
std::unique_ptr<TCPSocket> tcp_socket;
- tcp_socket.reset(new TCPSocket(fd, false));
+ tcp_socket.reset(new TCPSocket(fd, false, false));
// Try and get a socket option from this file descriptor to
// see if this is a socket and set m_is_socket accordingly.
int resuse;
@@ -720,7 +720,7 @@ ConnectionFileDescriptor::SocketListenAndAccept(llvm::StringRef s,
listening_socket_up.reset(socket);
socket = nullptr;
- error = listening_socket_up->Accept(s, m_child_processes_inherit, socket);
+ error = listening_socket_up->Accept(socket);
listening_socket_up.reset();
if (error_ptr)
*error_ptr = error;
diff --git a/source/Host/posix/DomainSocket.cpp b/source/Host/posix/DomainSocket.cpp
index 538979df2b6b..33c71268c2e3 100644
--- a/source/Host/posix/DomainSocket.cpp
+++ b/source/Host/posix/DomainSocket.cpp
@@ -56,19 +56,21 @@ bool SetSockAddr(llvm::StringRef name, const size_t name_offset,
return true;
}
-}
-
-DomainSocket::DomainSocket(NativeSocket socket)
- : Socket(socket, ProtocolUnixDomain, true) {}
+} // namespace
-DomainSocket::DomainSocket(bool child_processes_inherit, Error &error)
- : DomainSocket(
- CreateSocket(kDomain, kType, 0, child_processes_inherit, error)) {}
+DomainSocket::DomainSocket(bool should_close, bool child_processes_inherit)
+ : Socket(ProtocolUnixDomain, should_close, child_processes_inherit) {}
DomainSocket::DomainSocket(SocketProtocol protocol,
- bool child_processes_inherit, Error &error)
- : Socket(CreateSocket(kDomain, kType, 0, child_processes_inherit, error),
- protocol, true) {}
+ bool child_processes_inherit)
+ : Socket(protocol, true, child_processes_inherit) {}
+
+DomainSocket::DomainSocket(NativeSocket socket,
+ const DomainSocket &listen_socket)
+ : Socket(ProtocolUnixDomain, listen_socket.m_should_close_fd,
+ listen_socket.m_child_processes_inherit) {
+ m_socket = socket;
+}
Error DomainSocket::Connect(llvm::StringRef name) {
sockaddr_un saddr_un;
@@ -77,6 +79,9 @@ Error DomainSocket::Connect(llvm::StringRef name) {
return Error("Failed to set socket address");
Error error;
+ m_socket = CreateSocket(kDomain, kType, 0, m_child_processes_inherit, error);
+ if (error.Fail())
+ return error;
if (::connect(GetNativeSocket(), (struct sockaddr *)&saddr_un, saddr_un_len) <
0)
SetLastError(error);
@@ -93,6 +98,9 @@ Error DomainSocket::Listen(llvm::StringRef name, int backlog) {
DeleteSocketFile(name);
Error error;
+ m_socket = CreateSocket(kDomain, kType, 0, m_child_processes_inherit, error);
+ if (error.Fail())
+ return error;
if (::bind(GetNativeSocket(), (struct sockaddr *)&saddr_un, saddr_un_len) ==
0)
if (::listen(GetNativeSocket(), backlog) == 0)
@@ -102,13 +110,12 @@ Error DomainSocket::Listen(llvm::StringRef name, int backlog) {
return error;
}
-Error DomainSocket::Accept(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) {
+Error DomainSocket::Accept(Socket *&socket) {
Error error;
auto conn_fd = AcceptSocket(GetNativeSocket(), nullptr, nullptr,
- child_processes_inherit, error);
+ m_child_processes_inherit, error);
if (error.Success())
- socket = new DomainSocket(conn_fd);
+ socket = new DomainSocket(conn_fd, *this);
return error;
}
diff --git a/source/Host/posix/MainLoopPosix.cpp b/source/Host/posix/MainLoopPosix.cpp
deleted file mode 100644
index a73187e730f0..000000000000
--- a/source/Host/posix/MainLoopPosix.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-//===-- MainLoopPosix.cpp ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Host/posix/MainLoopPosix.h"
-#include "lldb/Utility/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cerrno>
-#include <csignal>
-#include <sys/select.h>
-#include <vector>
-
-using namespace lldb;
-using namespace lldb_private;
-
-static sig_atomic_t g_signal_flags[NSIG];
-
-static void SignalHandler(int signo, siginfo_t *info, void *) {
- assert(signo < NSIG);
- g_signal_flags[signo] = 1;
-}
-
-MainLoopPosix::~MainLoopPosix() {
- assert(m_read_fds.size() == 0);
- assert(m_signals.size() == 0);
-}
-
-MainLoopPosix::ReadHandleUP
-MainLoopPosix::RegisterReadObject(const IOObjectSP &object_sp,
- const Callback &callback, Error &error) {
- if (!object_sp || !object_sp->IsValid()) {
- error.SetErrorString("IO object is not valid.");
- return nullptr;
- }
-
- const bool inserted =
- m_read_fds.insert({object_sp->GetWaitableHandle(), callback}).second;
- if (!inserted) {
- error.SetErrorStringWithFormat("File descriptor %d already monitored.",
- object_sp->GetWaitableHandle());
- return nullptr;
- }
-
- return CreateReadHandle(object_sp);
-}
-
-// We shall block the signal, then install the signal handler. The signal will
-// be unblocked in
-// the Run() function to check for signal delivery.
-MainLoopPosix::SignalHandleUP
-MainLoopPosix::RegisterSignal(int signo, const Callback &callback,
- Error &error) {
- if (m_signals.find(signo) != m_signals.end()) {
- error.SetErrorStringWithFormat("Signal %d already monitored.", signo);
- return nullptr;
- }
-
- SignalInfo info;
- info.callback = callback;
- struct sigaction new_action;
- new_action.sa_sigaction = &SignalHandler;
- new_action.sa_flags = SA_SIGINFO;
- sigemptyset(&new_action.sa_mask);
- sigaddset(&new_action.sa_mask, signo);
-
- sigset_t old_set;
- if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) {
- error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n",
- ret);
- return nullptr;
- }
-
- info.was_blocked = sigismember(&old_set, signo);
- if (sigaction(signo, &new_action, &info.old_action) == -1) {
- error.SetErrorToErrno();
- if (!info.was_blocked)
- pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr);
- return nullptr;
- }
-
- m_signals.insert({signo, info});
- g_signal_flags[signo] = 0;
-
- return SignalHandleUP(new SignalHandle(*this, signo));
-}
-
-void MainLoopPosix::UnregisterReadObject(IOObject::WaitableHandle handle) {
- bool erased = m_read_fds.erase(handle);
- UNUSED_IF_ASSERT_DISABLED(erased);
- assert(erased);
-}
-
-void MainLoopPosix::UnregisterSignal(int signo) {
- // We undo the actions of RegisterSignal on a best-effort basis.
- auto it = m_signals.find(signo);
- assert(it != m_signals.end());
-
- sigaction(signo, &it->second.old_action, nullptr);
-
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, signo);
- pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set,
- nullptr);
-
- m_signals.erase(it);
-}
-
-Error MainLoopPosix::Run() {
- std::vector<int> signals;
- sigset_t sigmask;
- std::vector<int> read_fds;
- fd_set read_fd_set;
- m_terminate_request = false;
-
- // run until termination or until we run out of things to listen to
- while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
- // To avoid problems with callbacks changing the things we're supposed to
- // listen to, we
- // will store the *real* list of events separately.
- signals.clear();
- read_fds.clear();
- FD_ZERO(&read_fd_set);
- int nfds = 0;
-
- if (int ret = pthread_sigmask(SIG_SETMASK, nullptr, &sigmask))
- return Error("pthread_sigmask failed with error %d\n", ret);
-
- for (const auto &fd : m_read_fds) {
- read_fds.push_back(fd.first);
- FD_SET(fd.first, &read_fd_set);
- nfds = std::max(nfds, fd.first + 1);
- }
-
- for (const auto &sig : m_signals) {
- signals.push_back(sig.first);
- sigdelset(&sigmask, sig.first);
- }
-
- if (pselect(nfds, &read_fd_set, nullptr, nullptr, nullptr, &sigmask) ==
- -1 &&
- errno != EINTR)
- return Error(errno, eErrorTypePOSIX);
-
- for (int sig : signals) {
- if (g_signal_flags[sig] == 0)
- continue; // No signal
- g_signal_flags[sig] = 0;
-
- auto it = m_signals.find(sig);
- if (it == m_signals.end())
- continue; // Signal must have gotten unregistered in the meantime
-
- it->second.callback(*this); // Do the work
-
- if (m_terminate_request)
- return Error();
- }
-
- for (int fd : read_fds) {
- if (!FD_ISSET(fd, &read_fd_set))
- continue; // Not ready
-
- auto it = m_read_fds.find(fd);
- if (it == m_read_fds.end())
- continue; // File descriptor must have gotten unregistered in the
- // meantime
-
- it->second(*this); // Do the work
-
- if (m_terminate_request)
- return Error();
- }
- }
- return Error();
-}
diff --git a/source/Interpreter/CommandInterpreter.cpp b/source/Interpreter/CommandInterpreter.cpp
index de27f7be30d3..8703bc97f06e 100644
--- a/source/Interpreter/CommandInterpreter.cpp
+++ b/source/Interpreter/CommandInterpreter.cpp
@@ -645,8 +645,8 @@ void CommandInterpreter::LoadCommandDictionary() {
"gdb-remote [<hostname>:]<portnum>", 2, 0, false));
if (connect_gdb_remote_cmd_ap.get()) {
if (connect_gdb_remote_cmd_ap->AddRegexCommand(
- "^([^:]+:[[:digit:]]+)$",
- "process connect --plugin gdb-remote connect://%1") &&
+ "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$",
+ "process connect --plugin gdb-remote connect://%1:%2") &&
connect_gdb_remote_cmd_ap->AddRegexCommand(
"^([[:digit:]]+)$",
"process connect --plugin gdb-remote connect://localhost:%1")) {
diff --git a/source/Interpreter/OptionValueEnumeration.cpp b/source/Interpreter/OptionValueEnumeration.cpp
index d3899677ba53..2bff0bdcec37 100644
--- a/source/Interpreter/OptionValueEnumeration.cpp
+++ b/source/Interpreter/OptionValueEnumeration.cpp
@@ -37,7 +37,7 @@ void OptionValueEnumeration::DumpValue(const ExecutionContext *exe_ctx,
const size_t count = m_enumerations.GetSize();
for (size_t i = 0; i < count; ++i) {
if (m_enumerations.GetValueAtIndexUnchecked(i).value == m_current_value) {
- strm.PutCString(m_enumerations.GetCStringAtIndex(i));
+ strm.PutCString(m_enumerations.GetCStringAtIndex(i).GetStringRef());
return;
}
}
@@ -58,8 +58,7 @@ Error OptionValueEnumeration::SetValueFromString(llvm::StringRef value,
case eVarSetOperationAssign: {
ConstString const_enumerator_name(value.trim());
const EnumerationMapEntry *enumerator_entry =
- m_enumerations.FindFirstValueForName(
- const_enumerator_name.GetStringRef());
+ m_enumerations.FindFirstValueForName(const_enumerator_name);
if (enumerator_entry) {
m_current_value = enumerator_entry->value.value;
NotifyValueChanged();
@@ -69,10 +68,10 @@ Error OptionValueEnumeration::SetValueFromString(llvm::StringRef value,
const size_t count = m_enumerations.GetSize();
if (count) {
error_strm.Printf(", valid values are: %s",
- m_enumerations.GetCStringAtIndex(0).str().c_str());
+ m_enumerations.GetCStringAtIndex(0).GetCString());
for (size_t i = 1; i < count; ++i) {
error_strm.Printf(", %s",
- m_enumerations.GetCStringAtIndex(i).str().c_str());
+ m_enumerations.GetCStringAtIndex(i).GetCString());
}
}
error.SetErrorString(error_strm.GetString());
@@ -99,7 +98,7 @@ void OptionValueEnumeration::SetEnumerations(
ConstString const_enumerator_name(enumerators[i].string_value);
EnumeratorInfo enumerator_info = {enumerators[i].value,
enumerators[i].usage};
- m_enumerations.Append(const_enumerator_name.GetStringRef(),
+ m_enumerations.Append(const_enumerator_name,
enumerator_info);
}
m_enumerations.Sort();
@@ -119,14 +118,14 @@ size_t OptionValueEnumeration::AutoComplete(
const uint32_t num_enumerators = m_enumerations.GetSize();
if (!s.empty()) {
for (size_t i = 0; i < num_enumerators; ++i) {
- llvm::StringRef name = m_enumerations.GetCStringAtIndex(i);
+ llvm::StringRef name = m_enumerations.GetCStringAtIndex(i).GetStringRef();
if (name.startswith(s))
matches.AppendString(name);
}
} else {
// only suggest "true" or "false" by default
for (size_t i = 0; i < num_enumerators; ++i)
- matches.AppendString(m_enumerations.GetCStringAtIndex(i));
+ matches.AppendString(m_enumerations.GetCStringAtIndex(i).GetStringRef());
}
return matches.GetSize();
}
diff --git a/source/Interpreter/OptionValueProperties.cpp b/source/Interpreter/OptionValueProperties.cpp
index 10370c2f667f..732769f6e6df 100644
--- a/source/Interpreter/OptionValueProperties.cpp
+++ b/source/Interpreter/OptionValueProperties.cpp
@@ -59,7 +59,7 @@ void OptionValueProperties::Initialize(const PropertyDefinition *defs) {
for (size_t i = 0; defs[i].name; ++i) {
Property property(defs[i]);
assert(property.IsValid());
- m_name_to_index.Append(property.GetName(), m_properties.size());
+ m_name_to_index.Append(ConstString(property.GetName()), m_properties.size());
property.GetValue()->SetParent(shared_from_this());
m_properties.push_back(property);
}
@@ -78,7 +78,7 @@ void OptionValueProperties::AppendProperty(const ConstString &name,
bool is_global,
const OptionValueSP &value_sp) {
Property property(name, desc, is_global, value_sp);
- m_name_to_index.Append(name.GetStringRef(), m_properties.size());
+ m_name_to_index.Append(name, m_properties.size());
m_properties.push_back(property);
value_sp->SetParent(shared_from_this());
m_name_to_index.Sort();
@@ -108,7 +108,7 @@ OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx,
const ConstString &key,
bool will_modify) const {
lldb::OptionValueSP value_sp;
- size_t idx = m_name_to_index.Find(key.GetStringRef(), SIZE_MAX);
+ size_t idx = m_name_to_index.Find(key, SIZE_MAX);
if (idx < m_properties.size())
value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue();
return value_sp;
@@ -218,7 +218,7 @@ Error OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx,
uint32_t
OptionValueProperties::GetPropertyIndex(const ConstString &name) const {
- return m_name_to_index.Find(name.GetStringRef(), SIZE_MAX);
+ return m_name_to_index.Find(name, SIZE_MAX);
}
const Property *
@@ -227,7 +227,7 @@ OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx,
const ConstString &name) const {
return GetPropertyAtIndex(
exe_ctx, will_modify,
- m_name_to_index.Find(name.GetStringRef(), SIZE_MAX));
+ m_name_to_index.Find(name, SIZE_MAX));
}
const Property *OptionValueProperties::GetPropertyAtIndex(
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index fe42a5ed9214..1ae9418e4d9c 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -271,144 +271,6 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier(
return false;
}
-class CPPRuntimeEquivalents {
-public:
- CPPRuntimeEquivalents() {
- m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, "
- "std::allocator<char> >")
- .GetStringRef(),
- ConstString("basic_string<char>"));
-
- // these two (with a prefixed std::) occur when c++stdlib string class
- // occurs as a template argument in some STL container
- m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, "
- "std::allocator<char> >")
- .GetStringRef(),
- ConstString("std::basic_string<char>"));
-
- m_impl.Sort();
- }
-
- void Add(ConstString &type_name, ConstString &type_equivalent) {
- m_impl.Insert(type_name.GetStringRef(), type_equivalent);
- }
-
- uint32_t FindExactMatches(ConstString &type_name,
- std::vector<ConstString> &equivalents) {
- uint32_t count = 0;
-
- for (ImplData match =
- m_impl.FindFirstValueForName(type_name.GetStringRef());
- match != nullptr; match = m_impl.FindNextValueForName(match)) {
- equivalents.push_back(match->value);
- count++;
- }
-
- return count;
- }
-
- // partial matches can occur when a name with equivalents is a template
- // argument.
- // e.g. we may have "class Foo" be a match for "struct Bar". if we have a
- // typename
- // such as "class Templatized<class Foo, Anything>" we want this to be
- // replaced with
- // "class Templatized<struct Bar, Anything>". Since partial matching is time
- // consuming
- // once we get a partial match, we add it to the exact matches list for faster
- // retrieval
- uint32_t FindPartialMatches(ConstString &type_name,
- std::vector<ConstString> &equivalents) {
- uint32_t count = 0;
-
- llvm::StringRef type_name_cstr = type_name.GetStringRef();
-
- size_t items_count = m_impl.GetSize();
-
- for (size_t item = 0; item < items_count; item++) {
- llvm::StringRef key_cstr = m_impl.GetCStringAtIndex(item);
- if (type_name_cstr.contains(key_cstr)) {
- count += AppendReplacements(type_name_cstr, key_cstr, equivalents);
- }
- }
-
- return count;
- }
-
-private:
- std::string &replace(std::string &target, std::string &pattern,
- std::string &with) {
- size_t pos;
- size_t pattern_len = pattern.size();
-
- while ((pos = target.find(pattern)) != std::string::npos)
- target.replace(pos, pattern_len, with);
-
- return target;
- }
-
- uint32_t AppendReplacements(llvm::StringRef original,
- llvm::StringRef matching_key,
- std::vector<ConstString> &equivalents) {
- std::string matching_key_str(matching_key);
- ConstString original_const(original);
-
- uint32_t count = 0;
-
- for (ImplData match = m_impl.FindFirstValueForName(matching_key);
- match != nullptr; match = m_impl.FindNextValueForName(match)) {
- std::string target(original);
- std::string equiv_class(match->value.AsCString());
-
- replace(target, matching_key_str, equiv_class);
-
- ConstString target_const(target.c_str());
-
-// you will most probably want to leave this off since it might make this map
-// grow indefinitely
-#ifdef ENABLE_CPP_EQUIVALENTS_MAP_TO_GROW
- Add(original_const, target_const);
-#endif
- equivalents.push_back(target_const);
-
- count++;
- }
-
- return count;
- }
-
- typedef UniqueCStringMap<ConstString> Impl;
- typedef const Impl::Entry *ImplData;
- Impl m_impl;
-};
-
-static CPPRuntimeEquivalents &GetEquivalentsMap() {
- static CPPRuntimeEquivalents g_equivalents_map;
- return g_equivalents_map;
-}
-
-uint32_t
-CPlusPlusLanguage::FindEquivalentNames(ConstString type_name,
- std::vector<ConstString> &equivalents) {
- uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents);
-
- bool might_have_partials =
- (count == 0) // if we have a full name match just use it
- && (strchr(type_name.AsCString(), '<') !=
- nullptr // we should only have partial matches when templates are
- // involved, check that we have
- && strchr(type_name.AsCString(), '>') != nullptr); // angle brackets
- // in the type_name
- // before trying to
- // scan for partial
- // matches
-
- if (might_have_partials)
- count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
-
- return count;
-}
-
/// Given a mangled function `mangled`, replace all the primitive function type
/// arguments of `search` with type `replace`.
static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
index 056cced2808a..7380ef321305 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h
@@ -119,18 +119,6 @@ public:
llvm::StringRef &context,
llvm::StringRef &identifier);
- // in some cases, compilers will output different names for one same type.
- // when that happens, it might be impossible
- // to construct SBType objects for a valid type, because the name that is
- // available is not the same as the name that
- // can be used as a search key in FindTypes(). the equivalents map here is
- // meant to return possible alternative names
- // for a type through which a search can be conducted. Currently, this is only
- // enabled for C++ but can be extended
- // to ObjC or other languages if necessary
- static uint32_t FindEquivalentNames(ConstString type_name,
- std::vector<ConstString> &equivalents);
-
// Given a mangled function name, calculates some alternative manglings since
// the compiler mangling may not line up with the symbol we are expecting
static uint32_t
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 50d4510ec5f9..293d64075921 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -219,6 +219,7 @@ size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
CalculateNumChildren() {
static ConstString g___pair3_("__pair3_");
static ConstString g___first_("__first_");
+ static ConstString g___value_("__value_");
if (m_count != UINT32_MAX)
return m_count;
@@ -227,7 +228,22 @@ size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::
ValueObjectSP m_item(m_tree->GetChildMemberWithName(g___pair3_, true));
if (!m_item)
return 0;
- m_item = m_item->GetChildMemberWithName(g___first_, true);
+
+ switch (m_item->GetCompilerType().GetNumDirectBaseClasses()) {
+ case 1:
+ // Assume a pre llvm r300140 __compressed_pair implementation:
+ m_item = m_item->GetChildMemberWithName(g___first_, true);
+ break;
+ case 2: {
+ // Assume a post llvm r300140 __compressed_pair implementation:
+ ValueObjectSP first_elem_parent = m_item->GetChildAtIndex(0, true);
+ m_item = first_elem_parent->GetChildMemberWithName(g___value_, true);
+ break;
+ }
+ default:
+ return false;
+ }
+
if (!m_item)
return 0;
m_count = m_item->GetValueAsUnsigned(0);
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
index c3566b7c6bfb..526bae6900f5 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp
@@ -94,9 +94,30 @@ lldb::ValueObjectSP lldb_private::formatters::
node_sp->GetChildMemberWithName(ConstString("__hash_"), true);
if (!hash_sp || !value_sp) {
if (!m_element_type) {
- auto first_sp = m_backend.GetChildAtNamePath({ConstString("__table_"),
- ConstString("__p1_"),
- ConstString("__first_")});
+ auto p1_sp = m_backend.GetChildAtNamePath({ConstString("__table_"),
+ ConstString("__p1_")});
+ if (!p1_sp)
+ return nullptr;
+
+ ValueObjectSP first_sp = nullptr;
+ switch (p1_sp->GetCompilerType().GetNumDirectBaseClasses()) {
+ case 1:
+ // Assume a pre llvm r300140 __compressed_pair implementation:
+ first_sp = p1_sp->GetChildMemberWithName(ConstString("__first_"),
+ true);
+ break;
+ case 2: {
+ // Assume a post llvm r300140 __compressed_pair implementation:
+ ValueObjectSP first_elem_parent_sp =
+ p1_sp->GetChildAtIndex(0, true);
+ first_sp = p1_sp->GetChildMemberWithName(ConstString("__value_"),
+ true);
+ break;
+ }
+ default:
+ return nullptr;
+ }
+
if (!first_sp)
return nullptr;
m_element_type = first_sp->GetCompilerType();
@@ -152,22 +173,39 @@ bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd::
m_backend.GetChildMemberWithName(ConstString("__table_"), true);
if (!table_sp)
return false;
- ValueObjectSP num_elements_sp = table_sp->GetChildAtNamePath(
- {ConstString("__p2_"), ConstString("__first_")});
+
+ ValueObjectSP p2_sp = table_sp->GetChildMemberWithName(
+ ConstString("__p2_"), true);
+ ValueObjectSP num_elements_sp = nullptr;
+ llvm::SmallVector<ConstString, 3> next_path;
+ switch (p2_sp->GetCompilerType().GetNumDirectBaseClasses()) {
+ case 1:
+ // Assume a pre llvm r300140 __compressed_pair implementation:
+ num_elements_sp = p2_sp->GetChildMemberWithName(
+ ConstString("__first_"), true);
+ next_path.append({ConstString("__p1_"), ConstString("__first_"),
+ ConstString("__next_")});
+ break;
+ case 2: {
+ // Assume a post llvm r300140 __compressed_pair implementation:
+ ValueObjectSP first_elem_parent = p2_sp->GetChildAtIndex(0, true);
+ num_elements_sp = first_elem_parent->GetChildMemberWithName(
+ ConstString("__value_"), true);
+ next_path.append({ConstString("__p1_"), ConstString("__value_"),
+ ConstString("__next_")});
+ break;
+ }
+ default:
+ return false;
+ }
+
if (!num_elements_sp)
return false;
m_num_elements = num_elements_sp->GetValueAsUnsigned(0);
- m_tree =
- table_sp
- ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"),
- ConstString("__next_")})
- .get();
+ m_tree = table_sp->GetChildAtNamePath(next_path).get();
if (m_num_elements > 0)
m_next_element =
- table_sp
- ->GetChildAtNamePath({ConstString("__p1_"), ConstString("__first_"),
- ConstString("__next_")})
- .get();
+ table_sp->GetChildAtNamePath(next_path).get();
return false;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
index 2843201e2ed9..96d7e51deba4 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp
@@ -127,8 +127,25 @@ bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() {
m_backend.GetChildMemberWithName(ConstString("__end_cap_"), true));
if (!data_type_finder_sp)
return false;
- data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(
+
+ switch (data_type_finder_sp->GetCompilerType().GetNumDirectBaseClasses()) {
+ case 1:
+ // Assume a pre llvm r300140 __compressed_pair implementation:
+ data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName(
ConstString("__first_"), true);
+ break;
+ case 2: {
+ // Assume a post llvm r300140 __compressed_pair implementation:
+ ValueObjectSP first_elem_parent_sp =
+ data_type_finder_sp->GetChildAtIndex(0, true);
+ data_type_finder_sp = first_elem_parent_sp->GetChildMemberWithName(
+ ConstString("__value_"), true);
+ break;
+ }
+ default:
+ return false;
+ }
+
if (!data_type_finder_sp)
return false;
m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType();
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 07b4ae5e0add..e99fd74a352f 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -355,9 +355,14 @@ public:
}
}
+ clang::IdentifierInfo **identifier_infos = selector_components.data();
+ if (!identifier_infos) {
+ return NULL;
+ }
+
clang::Selector sel = ast_ctx.Selectors.getSelector(
is_zero_argument ? 0 : selector_components.size(),
- selector_components.data());
+ identifier_infos);
clang::QualType ret_type =
ClangUtil::GetQualType(type_realizer_sp->RealizeType(
diff --git a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
index b74da3300170..928157516808 100644
--- a/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ b/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -158,7 +158,7 @@ size_t ObjectContainerBSDArchive::Archive::ParseObjects() {
size_t obj_idx = m_objects.size();
m_objects.push_back(obj);
// Insert all of the C strings out of order for now...
- m_object_name_to_index_map.Append(obj.ar_name.GetStringRef(), obj_idx);
+ m_object_name_to_index_map.Append(obj.ar_name, obj_idx);
offset += obj.ar_file_size;
obj.Clear();
} while (data.ValidOffset(offset));
@@ -174,8 +174,7 @@ ObjectContainerBSDArchive::Archive::FindObject(
const ConstString &object_name,
const llvm::sys::TimePoint<> &object_mod_time) {
const ObjectNameToIndexMap::Entry *match =
- m_object_name_to_index_map.FindFirstValueForName(
- object_name.GetStringRef());
+ m_object_name_to_index_map.FindFirstValueForName(object_name);
if (match) {
if (object_mod_time != llvm::sys::TimePoint<>()) {
const uint64_t object_date = llvm::sys::toTimeT(object_mod_time);
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index 6e2001b21630..0720cca27341 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1808,10 +1808,10 @@ DataExtractor ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) {
segment_header->p_filesz);
}
-std::string
+llvm::StringRef
ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
size_t pos = symbol_name.find('@');
- return symbol_name.substr(0, pos).str();
+ return symbol_name.substr(0, pos);
}
//----------------------------------------------------------------------
@@ -2418,7 +2418,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
.emplace(sect_name.GetCString(),
module_section_list->FindSectionByName(sect_name))
.first;
- if (section_it->second && section_it->second->GetFileSize())
+ if (section_it->second)
symbol_section_sp = section_it->second;
}
diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
index 98bd9abb1932..9b2d58b7be82 100644
--- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
+++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
@@ -152,7 +152,7 @@ public:
// Returns segment data for the given index.
lldb_private::DataExtractor GetSegmentDataByIndex(lldb::user_id_t id);
- std::string
+ llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override;
private:
diff --git a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
index 0c5e478d470e..034518c1d2e3 100644
--- a/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.cpp
@@ -67,7 +67,7 @@ static Error DeleteForwardPortWithAdb(uint16_t local_port,
static Error FindUnusedPort(uint16_t &port) {
Error error;
- std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(false, error));
+ std::unique_ptr<TCPSocket> tcp_socket(new TCPSocket(true, false));
if (error.Fail())
return error;
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 1d8b759d2fa8..8aec35d09ce5 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -3900,10 +3900,9 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (src_name) {
ConstString src_const_name(src_name);
if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
- src_name_to_die_artificial.Append(src_const_name.GetStringRef(),
- src_die);
+ src_name_to_die_artificial.Append(src_const_name, src_die);
else
- src_name_to_die.Append(src_const_name.GetStringRef(), src_die);
+ src_name_to_die.Append(src_const_name, src_die);
}
}
}
@@ -3920,10 +3919,9 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (dst_name) {
ConstString dst_const_name(dst_name);
if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
- dst_name_to_die_artificial.Append(dst_const_name.GetStringRef(),
- dst_die);
+ dst_name_to_die_artificial.Append(dst_const_name, dst_die);
else
- dst_name_to_die.Append(dst_const_name.GetStringRef(), dst_die);
+ dst_name_to_die.Append(dst_const_name, dst_die);
}
}
}
@@ -4036,7 +4034,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
src_name_to_die.Sort();
for (idx = 0; idx < dst_size; ++idx) {
- llvm::StringRef dst_name = dst_name_to_die.GetCStringAtIndex(idx);
+ ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx);
dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
src_die = src_name_to_die.Find(dst_name, DWARFDIE());
@@ -4091,7 +4089,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
dst_name_to_die_artificial.Sort();
for (idx = 0; idx < src_size_artificial; ++idx) {
- llvm::StringRef src_name_artificial =
+ ConstString src_name_artificial =
src_name_to_die_artificial.GetCStringAtIndex(idx);
src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
dst_die =
@@ -4135,13 +4133,13 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
if (dst_size_artificial) {
for (idx = 0; idx < dst_size_artificial; ++idx) {
- llvm::StringRef dst_name_artificial =
+ ConstString dst_name_artificial =
dst_name_to_die_artificial.GetCStringAtIndex(idx);
dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
if (log)
log->Printf("warning: need to create artificial method for 0x%8.8x for "
"method '%s'",
- dst_die.GetOffset(), dst_name_artificial.str().c_str());
+ dst_die.GetOffset(), dst_name_artificial.GetCString());
failures.Append(dst_die);
}
diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
index f5f979caa38e..c97680eda0fe 100644
--- a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -28,11 +28,11 @@ void NameToDIE::Finalize() {
}
void NameToDIE::Insert(const ConstString &name, const DIERef &die_ref) {
- m_map.Append(name.GetStringRef(), die_ref);
+ m_map.Append(name, die_ref);
}
size_t NameToDIE::Find(const ConstString &name, DIEArray &info_array) const {
- return m_map.GetValues(name.GetStringRef(), info_array);
+ return m_map.GetValues(name, info_array);
}
size_t NameToDIE::Find(const RegularExpression &regex,
@@ -55,15 +55,15 @@ size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
void NameToDIE::Dump(Stream *s) {
const uint32_t size = m_map.GetSize();
for (uint32_t i = 0; i < size; ++i) {
- llvm::StringRef cstr = m_map.GetCStringAtIndex(i);
+ ConstString cstr = m_map.GetCStringAtIndex(i);
const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
- s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.data(),
- die_ref.cu_offset, die_ref.die_offset, cstr.str().c_str());
+ s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.GetCString(),
+ die_ref.cu_offset, die_ref.die_offset, cstr.GetCString());
}
}
void NameToDIE::ForEach(
- std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const
+ std::function<bool(ConstString name, const DIERef &die_ref)> const
&callback) const {
const uint32_t size = m_map.GetSize();
for (uint32_t i = 0; i < size; ++i) {
diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.h b/source/Plugins/SymbolFile/DWARF/NameToDIE.h
index e3fe321338a2..bba44fda3c04 100644
--- a/source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -43,7 +43,8 @@ public:
DIEArray &info_array) const;
void
- ForEach(std::function<bool(llvm::StringRef name, const DIERef &die_ref)> const
+ ForEach(std::function<bool(lldb_private::ConstString name,
+ const DIERef &die_ref)> const
&callback) const;
protected:
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 973b5ef9fb46..8c2fc3d3aa42 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1917,6 +1917,12 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec,
return sc_list.GetSize() - prev_size;
}
+void SymbolFileDWARF::PreloadSymbols() {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetObjectFile()->GetModule()->GetMutex());
+ Index();
+}
+
void SymbolFileDWARF::Index() {
if (m_indexed)
return;
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 14b29fa44fa3..9b1eb1d76fea 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -226,6 +226,8 @@ public:
const lldb_private::ConstString &name,
const lldb_private::CompilerDeclContext *parent_decl_ctx) override;
+ void PreloadSymbols() override;
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp
index 6ad353099bc5..8e2576aaec95 100644
--- a/source/Symbol/ClangASTContext.cpp
+++ b/source/Symbol/ClangASTContext.cpp
@@ -378,10 +378,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
// Set some properties which depend solely on the input kind; it would be nice
// to move these to the language standard, and have the driver resolve the
// input kind + language standard.
- if (IK == IK_Asm) {
+ if (IK.getLanguage() == InputKind::Asm) {
Opts.AsmPreprocessor = 1;
- } else if (IK == IK_ObjC || IK == IK_ObjCXX || IK == IK_PreprocessedObjC ||
- IK == IK_PreprocessedObjCXX) {
+ } else if (IK.isObjectiveC()) {
Opts.ObjC1 = Opts.ObjC2 = 1;
}
@@ -389,30 +388,24 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
if (LangStd == LangStandard::lang_unspecified) {
// Based on the base language, pick one.
- switch (IK) {
- case IK_None:
- case IK_AST:
- case IK_LLVM_IR:
- case IK_RenderScript:
+ switch (IK.getLanguage()) {
+ case InputKind::Unknown:
+ case InputKind::LLVM_IR:
+ case InputKind::RenderScript:
llvm_unreachable("Invalid input kind!");
- case IK_OpenCL:
- LangStd = LangStandard::lang_opencl;
+ case InputKind::OpenCL:
+ LangStd = LangStandard::lang_opencl10;
break;
- case IK_CUDA:
- case IK_PreprocessedCuda:
+ case InputKind::CUDA:
LangStd = LangStandard::lang_cuda;
break;
- case IK_Asm:
- case IK_C:
- case IK_PreprocessedC:
- case IK_ObjC:
- case IK_PreprocessedObjC:
+ case InputKind::Asm:
+ case InputKind::C:
+ case InputKind::ObjC:
LangStd = LangStandard::lang_gnu99;
break;
- case IK_CXX:
- case IK_PreprocessedCXX:
- case IK_ObjCXX:
- case IK_PreprocessedObjCXX:
+ case InputKind::CXX:
+ case InputKind::ObjCXX:
LangStd = LangStandard::lang_gnucxx98;
break;
}
@@ -432,7 +425,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) {
Opts.WChar = true;
// OpenCL has some additional defaults.
- if (LangStd == LangStandard::lang_opencl) {
+ if (LangStd == LangStandard::lang_opencl10) {
Opts.OpenCL = 1;
Opts.AltiVec = 1;
Opts.CXXOperatorNames = 1;
@@ -784,8 +777,8 @@ IdentifierTable *ClangASTContext::getIdentifierTable() {
LangOptions *ClangASTContext::getLanguageOptions() {
if (m_language_options_ap.get() == nullptr) {
m_language_options_ap.reset(new LangOptions());
- ParseLangArgs(*m_language_options_ap, IK_ObjCXX, GetTargetTriple());
- // InitializeLangOptions(*m_language_options_ap, IK_ObjCXX);
+ ParseLangArgs(*m_language_options_ap, InputKind::ObjCXX, GetTargetTriple());
+ // InitializeLangOptions(*m_language_options_ap, InputKind::ObjCXX);
}
return m_language_options_ap.get();
}
@@ -961,75 +954,60 @@ ClangASTContext::GetBasicTypeEnumeration(const ConstString &name) {
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
// "void"
- g_type_map.Append(ConstString("void").GetStringRef(), eBasicTypeVoid);
+ g_type_map.Append(ConstString("void"), eBasicTypeVoid);
// "char"
- g_type_map.Append(ConstString("char").GetStringRef(), eBasicTypeChar);
- g_type_map.Append(ConstString("signed char").GetStringRef(),
- eBasicTypeSignedChar);
- g_type_map.Append(ConstString("unsigned char").GetStringRef(),
- eBasicTypeUnsignedChar);
- g_type_map.Append(ConstString("wchar_t").GetStringRef(), eBasicTypeWChar);
- g_type_map.Append(ConstString("signed wchar_t").GetStringRef(),
- eBasicTypeSignedWChar);
- g_type_map.Append(ConstString("unsigned wchar_t").GetStringRef(),
+ g_type_map.Append(ConstString("char"), eBasicTypeChar);
+ g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar);
+ g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar);
+ g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar);
+ g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar);
+ g_type_map.Append(ConstString("unsigned wchar_t"),
eBasicTypeUnsignedWChar);
// "short"
- g_type_map.Append(ConstString("short").GetStringRef(), eBasicTypeShort);
- g_type_map.Append(ConstString("short int").GetStringRef(),
- eBasicTypeShort);
- g_type_map.Append(ConstString("unsigned short").GetStringRef(),
- eBasicTypeUnsignedShort);
- g_type_map.Append(ConstString("unsigned short int").GetStringRef(),
+ g_type_map.Append(ConstString("short"), eBasicTypeShort);
+ g_type_map.Append(ConstString("short int"), eBasicTypeShort);
+ g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort);
+ g_type_map.Append(ConstString("unsigned short int"),
eBasicTypeUnsignedShort);
// "int"
- g_type_map.Append(ConstString("int").GetStringRef(), eBasicTypeInt);
- g_type_map.Append(ConstString("signed int").GetStringRef(),
- eBasicTypeInt);
- g_type_map.Append(ConstString("unsigned int").GetStringRef(),
- eBasicTypeUnsignedInt);
- g_type_map.Append(ConstString("unsigned").GetStringRef(),
- eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("int"), eBasicTypeInt);
+ g_type_map.Append(ConstString("signed int"), eBasicTypeInt);
+ g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt);
// "long"
- g_type_map.Append(ConstString("long").GetStringRef(), eBasicTypeLong);
- g_type_map.Append(ConstString("long int").GetStringRef(), eBasicTypeLong);
- g_type_map.Append(ConstString("unsigned long").GetStringRef(),
- eBasicTypeUnsignedLong);
- g_type_map.Append(ConstString("unsigned long int").GetStringRef(),
+ g_type_map.Append(ConstString("long"), eBasicTypeLong);
+ g_type_map.Append(ConstString("long int"), eBasicTypeLong);
+ g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong);
+ g_type_map.Append(ConstString("unsigned long int"),
eBasicTypeUnsignedLong);
// "long long"
- g_type_map.Append(ConstString("long long").GetStringRef(),
- eBasicTypeLongLong);
- g_type_map.Append(ConstString("long long int").GetStringRef(),
- eBasicTypeLongLong);
- g_type_map.Append(ConstString("unsigned long long").GetStringRef(),
+ g_type_map.Append(ConstString("long long"), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong);
+ g_type_map.Append(ConstString("unsigned long long"),
eBasicTypeUnsignedLongLong);
- g_type_map.Append(ConstString("unsigned long long int").GetStringRef(),
+ g_type_map.Append(ConstString("unsigned long long int"),
eBasicTypeUnsignedLongLong);
// "int128"
- g_type_map.Append(ConstString("__int128_t").GetStringRef(),
- eBasicTypeInt128);
- g_type_map.Append(ConstString("__uint128_t").GetStringRef(),
- eBasicTypeUnsignedInt128);
+ g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128);
+ g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128);
// Miscellaneous
- g_type_map.Append(ConstString("bool").GetStringRef(), eBasicTypeBool);
- g_type_map.Append(ConstString("float").GetStringRef(), eBasicTypeFloat);
- g_type_map.Append(ConstString("double").GetStringRef(), eBasicTypeDouble);
- g_type_map.Append(ConstString("long double").GetStringRef(),
- eBasicTypeLongDouble);
- g_type_map.Append(ConstString("id").GetStringRef(), eBasicTypeObjCID);
- g_type_map.Append(ConstString("SEL").GetStringRef(), eBasicTypeObjCSel);
- g_type_map.Append(ConstString("nullptr").GetStringRef(),
- eBasicTypeNullPtr);
+ g_type_map.Append(ConstString("bool"), eBasicTypeBool);
+ g_type_map.Append(ConstString("float"), eBasicTypeFloat);
+ g_type_map.Append(ConstString("double"), eBasicTypeDouble);
+ g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble);
+ g_type_map.Append(ConstString("id"), eBasicTypeObjCID);
+ g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel);
+ g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr);
g_type_map.Sort();
});
- return g_type_map.Find(name.GetStringRef(), eBasicTypeInvalid);
+ return g_type_map.Find(name, eBasicTypeInvalid);
}
return eBasicTypeInvalid;
}
diff --git a/source/Symbol/GoASTContext.cpp b/source/Symbol/GoASTContext.cpp
index 5ca173ae113c..6761a605e46b 100644
--- a/source/Symbol/GoASTContext.cpp
+++ b/source/Symbol/GoASTContext.cpp
@@ -598,33 +598,32 @@ GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) {
static llvm::once_flag g_once_flag;
llvm::call_once(g_once_flag, []() {
// "void"
- g_type_map.Append(ConstString("void").GetStringRef(), eBasicTypeVoid);
+ g_type_map.Append(ConstString("void"), eBasicTypeVoid);
// "int"
- g_type_map.Append(ConstString("int").GetStringRef(), eBasicTypeInt);
- g_type_map.Append(ConstString("uint").GetStringRef(),
- eBasicTypeUnsignedInt);
+ g_type_map.Append(ConstString("int"), eBasicTypeInt);
+ g_type_map.Append(ConstString("uint"), eBasicTypeUnsignedInt);
// Miscellaneous
- g_type_map.Append(ConstString("bool").GetStringRef(), eBasicTypeBool);
+ g_type_map.Append(ConstString("bool"), eBasicTypeBool);
// Others. Should these map to C types?
- g_type_map.Append(ConstString("byte").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("uint8").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("uint16").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("uint32").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("uint64").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("int8").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("int16").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("int32").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("int64").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("float32").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("float64").GetStringRef(), eBasicTypeOther);
- g_type_map.Append(ConstString("uintptr").GetStringRef(), eBasicTypeOther);
+ g_type_map.Append(ConstString("byte"), eBasicTypeOther);
+ g_type_map.Append(ConstString("uint8"), eBasicTypeOther);
+ g_type_map.Append(ConstString("uint16"), eBasicTypeOther);
+ g_type_map.Append(ConstString("uint32"), eBasicTypeOther);
+ g_type_map.Append(ConstString("uint64"), eBasicTypeOther);
+ g_type_map.Append(ConstString("int8"), eBasicTypeOther);
+ g_type_map.Append(ConstString("int16"), eBasicTypeOther);
+ g_type_map.Append(ConstString("int32"), eBasicTypeOther);
+ g_type_map.Append(ConstString("int64"), eBasicTypeOther);
+ g_type_map.Append(ConstString("float32"), eBasicTypeOther);
+ g_type_map.Append(ConstString("float64"), eBasicTypeOther);
+ g_type_map.Append(ConstString("uintptr"), eBasicTypeOther);
g_type_map.Sort();
});
- return g_type_map.Find(name.GetStringRef(), eBasicTypeInvalid);
+ return g_type_map.Find(name, eBasicTypeInvalid);
}
return eBasicTypeInvalid;
}
diff --git a/source/Symbol/SymbolFile.cpp b/source/Symbol/SymbolFile.cpp
index d7898919f45e..eb20b80f4916 100644
--- a/source/Symbol/SymbolFile.cpp
+++ b/source/Symbol/SymbolFile.cpp
@@ -21,6 +21,10 @@
using namespace lldb_private;
+void SymbolFile::PreloadSymbols() {
+ // No-op for most implementations.
+}
+
SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) {
std::unique_ptr<SymbolFile> best_symfile_ap;
if (obj_file != nullptr) {
diff --git a/source/Symbol/Symtab.cpp b/source/Symbol/Symtab.cpp
index 427029802634..1e241df0d90a 100644
--- a/source/Symbol/Symtab.cpp
+++ b/source/Symbol/Symtab.cpp
@@ -263,36 +263,35 @@ void Symtab::InitNameIndexes() {
continue;
const Mangled &mangled = symbol->GetMangled();
- entry.cstring = mangled.GetMangledName().GetStringRef();
- if (!entry.cstring.empty()) {
+ entry.cstring = mangled.GetMangledName();
+ if (entry.cstring) {
m_name_to_index.Append(entry);
if (symbol->ContainsLinkerAnnotations()) {
// If the symbol has linker annotations, also add the version without
// the annotations.
entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations(
- entry.cstring))
- .GetStringRef();
+ entry.cstring.GetStringRef()));
m_name_to_index.Append(entry);
}
const SymbolType symbol_type = symbol->GetType();
if (symbol_type == eSymbolTypeCode ||
symbol_type == eSymbolTypeResolver) {
- if (entry.cstring[0] == '_' && entry.cstring[1] == 'Z' &&
- (entry.cstring[2] != 'T' && // avoid virtual table, VTT structure,
- // typeinfo structure, and typeinfo
- // name
- entry.cstring[2] != 'G' && // avoid guard variables
- entry.cstring[2] != 'Z')) // named local entities (if we
+ llvm::StringRef entry_ref(entry.cstring.GetStringRef());
+ if (entry_ref[0] == '_' && entry_ref[1] == 'Z' &&
+ (entry_ref[2] != 'T' && // avoid virtual table, VTT structure,
+ // typeinfo structure, and typeinfo
+ // name
+ entry_ref[2] != 'G' && // avoid guard variables
+ entry_ref[2] != 'Z')) // named local entities (if we
// eventually handle eSymbolTypeData,
// we will want this back)
{
CPlusPlusLanguage::MethodName cxx_method(
mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus));
- entry.cstring =
- ConstString(cxx_method.GetBasename()).GetStringRef();
- if (!entry.cstring.empty()) {
+ entry.cstring = ConstString(cxx_method.GetBasename());
+ if (entry.cstring) {
// ConstString objects permanently store the string in the pool so
// calling
// GetCString() on the value gets us a const char * that will
@@ -300,7 +299,8 @@ void Symtab::InitNameIndexes() {
const char *const_context =
ConstString(cxx_method.GetContext()).GetCString();
- if (entry.cstring[0] == '~' ||
+ entry_ref = entry.cstring.GetStringRef();
+ if (entry_ref[0] == '~' ||
!cxx_method.GetQualifiers().empty()) {
// The first character of the demangled basename is '~' which
// means we have a class destructor. We can use this information
@@ -341,17 +341,15 @@ void Symtab::InitNameIndexes() {
}
}
- entry.cstring =
- mangled.GetDemangledName(symbol->GetLanguage()).GetStringRef();
- if (!entry.cstring.empty()) {
+ entry.cstring = mangled.GetDemangledName(symbol->GetLanguage());
+ if (entry.cstring) {
m_name_to_index.Append(entry);
if (symbol->ContainsLinkerAnnotations()) {
// If the symbol has linker annotations, also add the version without
// the annotations.
entry.cstring = ConstString(m_objfile->StripLinkerSymbolAnnotations(
- entry.cstring))
- .GetStringRef();
+ entry.cstring.GetStringRef()));
m_name_to_index.Append(entry);
}
}
@@ -359,15 +357,15 @@ void Symtab::InitNameIndexes() {
// If the demangled name turns out to be an ObjC name, and
// is a category name, add the version without categories to the index
// too.
- ObjCLanguage::MethodName objc_method(entry.cstring, true);
+ ObjCLanguage::MethodName objc_method(entry.cstring.GetStringRef(), true);
if (objc_method.IsValid(true)) {
- entry.cstring = objc_method.GetSelector().GetStringRef();
+ entry.cstring = objc_method.GetSelector();
m_selector_to_index.Append(entry);
ConstString objc_method_no_category(
objc_method.GetFullNameWithoutCategory(true));
if (objc_method_no_category) {
- entry.cstring = objc_method_no_category.GetStringRef();
+ entry.cstring = objc_method_no_category;
m_name_to_index.Append(entry);
}
}
@@ -427,6 +425,11 @@ void Symtab::InitNameIndexes() {
}
}
+void Symtab::PreloadSymbols() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ InitNameIndexes();
+}
+
void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
bool add_demangled, bool add_mangled,
NameToIndexMap &name_to_index_map) const {
@@ -444,15 +447,14 @@ void Symtab::AppendSymbolNamesToMap(const IndexCollection &indexes,
const Mangled &mangled = symbol->GetMangled();
if (add_demangled) {
- entry.cstring =
- mangled.GetDemangledName(symbol->GetLanguage()).GetStringRef();
- if (!entry.cstring.empty())
+ entry.cstring = mangled.GetDemangledName(symbol->GetLanguage());
+ if (entry.cstring)
name_to_index_map.Append(entry);
}
if (add_mangled) {
- entry.cstring = mangled.GetMangledName().GetStringRef();
- if (!entry.cstring.empty())
+ entry.cstring = mangled.GetMangledName();
+ if (entry.cstring)
name_to_index_map.Append(entry);
}
}
@@ -625,7 +627,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name,
if (!m_name_indexes_computed)
InitNameIndexes();
- return m_name_to_index.GetValues(symbol_name.GetStringRef(), indexes);
+ return m_name_to_index.GetValues(symbol_name, indexes);
}
return 0;
}
@@ -644,7 +646,7 @@ uint32_t Symtab::AppendSymbolIndexesWithName(const ConstString &symbol_name,
std::vector<uint32_t> all_name_indexes;
const size_t name_match_count =
- m_name_to_index.GetValues(symbol_name.GetStringRef(), all_name_indexes);
+ m_name_to_index.GetValues(symbol_name, all_name_indexes);
for (size_t i = 0; i < name_match_count; ++i) {
if (CheckSymbolAtIndex(all_name_indexes[i], symbol_debug_type,
symbol_visibility))
@@ -1068,8 +1070,6 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name,
size_t count = 0;
std::vector<uint32_t> symbol_indexes;
- llvm::StringRef name_cstr = name.GetStringRef();
-
// eFunctionNameTypeAuto should be pre-resolved by a call to
// Module::LookupInfo::LookupInfo()
assert((name_type_mask & eFunctionNameTypeAuto) == 0);
@@ -1107,7 +1107,7 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name,
if (!m_basename_to_index.IsEmpty()) {
const UniqueCStringMap<uint32_t>::Entry *match;
- for (match = m_basename_to_index.FindFirstValueForName(name_cstr);
+ for (match = m_basename_to_index.FindFirstValueForName(name);
match != nullptr;
match = m_basename_to_index.FindNextValueForName(match)) {
symbol_indexes.push_back(match->value);
@@ -1121,7 +1121,7 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name,
if (!m_method_to_index.IsEmpty()) {
const UniqueCStringMap<uint32_t>::Entry *match;
- for (match = m_method_to_index.FindFirstValueForName(name_cstr);
+ for (match = m_method_to_index.FindFirstValueForName(name);
match != nullptr;
match = m_method_to_index.FindNextValueForName(match)) {
symbol_indexes.push_back(match->value);
@@ -1135,7 +1135,7 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name,
if (!m_selector_to_index.IsEmpty()) {
const UniqueCStringMap<uint32_t>::Entry *match;
- for (match = m_selector_to_index.FindFirstValueForName(name_cstr);
+ for (match = m_selector_to_index.FindFirstValueForName(name);
match != nullptr;
match = m_selector_to_index.FindNextValueForName(match)) {
symbol_indexes.push_back(match->value);
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index df021e3953bc..5c9e92aaaa27 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -1870,6 +1870,11 @@ ModuleSP Target::GetSharedModule(const ModuleSpec &module_spec,
}
}
+ // Preload symbols outside of any lock, so hopefully we can do this for
+ // each library in parallel.
+ if (GetPreloadSymbols())
+ module_sp->PreloadSymbols();
+
if (old_module_sp &&
m_images.GetIndexForModule(old_module_sp.get()) !=
LLDB_INVALID_INDEX32) {
@@ -3277,6 +3282,8 @@ static PropertyDefinition g_properties[] = {
{"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr,
nullptr, "debugserver will detach (rather than killing) a process if it "
"loses connection with lldb."},
+ {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
+ "Enable loading of symbol tables before they are needed."},
{"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr,
"Disable Address Space Layout Randomization (ASLR)"},
{"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr,
@@ -3379,6 +3386,7 @@ enum {
ePropertyOutputPath,
ePropertyErrorPath,
ePropertyDetachOnError,
+ ePropertyPreloadSymbols,
ePropertyDisableASLR,
ePropertyDisableSTDIO,
ePropertyInlineStrategy,
@@ -3641,6 +3649,17 @@ bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) {
return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d);
}
+bool TargetProperties::GetPreloadSymbols() const {
+ const uint32_t idx = ePropertyPreloadSymbols;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
+}
+
+void TargetProperties::SetPreloadSymbols(bool b) {
+ const uint32_t idx = ePropertyPreloadSymbols;
+ m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
bool TargetProperties::GetDisableASLR() const {
const uint32_t idx = ePropertyDisableASLR;
return m_collection_sp->GetPropertyAtIndexAsBoolean(
diff --git a/source/Utility/ConstString.cpp b/source/Utility/ConstString.cpp
index 8adeb6f364ef..49cf8a6d864d 100644
--- a/source/Utility/ConstString.cpp
+++ b/source/Utility/ConstString.cpp
@@ -38,14 +38,13 @@ public:
static StringPoolEntryType &
GetStringMapEntryFromKeyData(const char *keyData) {
- char *ptr = const_cast<char *>(keyData) - sizeof(StringPoolEntryType);
- return *reinterpret_cast<StringPoolEntryType *>(ptr);
+ return StringPoolEntryType::GetStringMapEntryFromKeyData(keyData);
}
- size_t GetConstCStringLength(const char *ccstr) const {
+ static size_t GetConstCStringLength(const char *ccstr) {
if (ccstr != nullptr) {
- const uint8_t h = hash(llvm::StringRef(ccstr));
- llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
+ // Since the entry is read only, and we derive the entry entirely from the
+ // pointer, we don't need the lock.
const StringPoolEntryType &entry = GetStringMapEntryFromKeyData(ccstr);
return entry.getKey().size();
}
@@ -218,10 +217,8 @@ bool ConstString::operator<(const ConstString &rhs) const {
if (m_string == rhs.m_string)
return false;
- llvm::StringRef lhs_string_ref(m_string,
- StringPool().GetConstCStringLength(m_string));
- llvm::StringRef rhs_string_ref(
- rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
+ llvm::StringRef lhs_string_ref(GetStringRef());
+ llvm::StringRef rhs_string_ref(rhs.GetStringRef());
// If both have valid C strings, then return the comparison
if (lhs_string_ref.data() && rhs_string_ref.data())
@@ -240,7 +237,7 @@ Stream &lldb_private::operator<<(Stream &s, const ConstString &str) {
}
size_t ConstString::GetLength() const {
- return StringPool().GetConstCStringLength(m_string);
+ return Pool::GetConstCStringLength(m_string);
}
bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
@@ -255,10 +252,8 @@ bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
return false;
// perform case insensitive equality test
- llvm::StringRef lhs_string_ref(
- lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string));
- llvm::StringRef rhs_string_ref(
- rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
+ llvm::StringRef lhs_string_ref(lhs.GetStringRef());
+ llvm::StringRef rhs_string_ref(rhs.GetStringRef());
return lhs_string_ref.equals_lower(rhs_string_ref);
}
@@ -270,10 +265,8 @@ int ConstString::Compare(const ConstString &lhs, const ConstString &rhs,
if (lhs_cstr == rhs_cstr)
return 0;
if (lhs_cstr && rhs_cstr) {
- llvm::StringRef lhs_string_ref(
- lhs_cstr, StringPool().GetConstCStringLength(lhs_cstr));
- llvm::StringRef rhs_string_ref(
- rhs_cstr, StringPool().GetConstCStringLength(rhs_cstr));
+ llvm::StringRef lhs_string_ref(lhs.GetStringRef());
+ llvm::StringRef rhs_string_ref(rhs.GetStringRef());
if (case_sensitive) {
return lhs_string_ref.compare(rhs_string_ref);
diff --git a/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index e0d1b68db702..d97b438ce8e5 100644
--- a/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -101,6 +101,7 @@
AF48558D1D75127500D19C07 /* StdStringExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF48558B1D75126800D19C07 /* StdStringExtractor.cpp */; };
AFA3FCA11E39984900218D5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 49D404611E39260F00570CDC /* Foundation.framework */; };
AFEC3364194A8B0B00FF05C6 /* Genealogy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */; };
+ D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@@ -219,6 +220,7 @@
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PseudoTerminal.cpp; sourceTree = "<group>"; };
AF67AC000D34604D0022D128 /* PseudoTerminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PseudoTerminal.h; sourceTree = "<group>"; };
AFEC3363194A8B0B00FF05C6 /* Genealogy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Genealogy.cpp; sourceTree = "<group>"; };
+ D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = SocketAddress.cpp; path = ../../source/Host/common/SocketAddress.cpp; sourceTree = "<group>"; };
ED128B7918E1F163003F6A7B /* libpmenergy.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpmenergy.dylib; path = usr/lib/libpmenergy.dylib; sourceTree = SDKROOT; };
ED128B7A18E1F163003F6A7B /* libpmsample.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libpmsample.dylib; path = usr/lib/libpmsample.dylib; sourceTree = SDKROOT; };
EF88788B0D9C7558001831DA /* com.apple.debugserver.applist.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.applist.plist; sourceTree = "<group>"; };
@@ -251,6 +253,7 @@
08FB7794FE84155DC02AAC07 /* dbgnub */ = {
isa = PBXGroup;
children = (
+ D6631CA81E848FE9006A7B11 /* SocketAddress.cpp */,
26ACA3330D3E94F200A2120B /* Framework */,
26C637D50C71334A0024798E /* source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
@@ -577,6 +580,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ D6631CA91E848FE9006A7B11 /* SocketAddress.cpp in Sources */,
26CE05A7115C360D0022F371 /* DNBError.cpp in Sources */,
26CE05A8115C36170022F371 /* DNBThreadResumeActions.cpp in Sources */,
26CE05A9115C36250022F371 /* debugserver.cpp in Sources */,
diff --git a/tools/debugserver/source/CMakeLists.txt b/tools/debugserver/source/CMakeLists.txt
index 782c946f702f..775a1a127b6f 100644
--- a/tools/debugserver/source/CMakeLists.txt
+++ b/tools/debugserver/source/CMakeLists.txt
@@ -62,6 +62,7 @@ set(lldbDebugserverCommonSources
StdStringExtractor.cpp
# JSON reader depends on the following LLDB-common files
${LLDB_SOURCE_DIR}/source/Host/common/StringConvert.cpp
+ ${LLDB_SOURCE_DIR}/source/Host/common/SocketAddress.cpp
# end JSON reader dependencies
libdebugserver.cpp
PseudoTerminal.cpp
diff --git a/tools/debugserver/source/RNBSocket.cpp b/tools/debugserver/source/RNBSocket.cpp
index a8d119e455fa..62a3e4f9adf5 100644
--- a/tools/debugserver/source/RNBSocket.cpp
+++ b/tools/debugserver/source/RNBSocket.cpp
@@ -17,10 +17,15 @@
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
+#include <map>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
+#include <sys/event.h>
#include <termios.h>
+#include <vector>
+
+#include "lldb/Host/SocketAddress.h"
#ifdef WITH_LOCKDOWN
#include "lockdown.h"
@@ -66,176 +71,161 @@ rnb_err_t RNBSocket::Listen(const char *listen_host, uint16_t port,
// Disconnect without saving errno
Disconnect(false);
- // Now figure out the hostname that will be attaching and palce it into
- struct sockaddr_in listen_addr;
- ::memset(&listen_addr, 0, sizeof listen_addr);
- listen_addr.sin_len = sizeof listen_addr;
- listen_addr.sin_family = AF_INET;
- listen_addr.sin_port = htons(port);
- listen_addr.sin_addr.s_addr = INADDR_ANY;
-
- if (!ResolveIPV4HostName(listen_host, listen_addr.sin_addr.s_addr)) {
- DNBLogThreaded("error: failed to resolve connecting host '%s'",
- listen_host);
+ DNBError err;
+ int queue_id = kqueue();
+ if (queue_id < 0) {
+ err.SetError(errno, DNBError::MachKernel);
+ err.LogThreaded("error: failed to create kqueue.");
return rnb_err;
}
- DNBError err;
- int listen_fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (listen_fd == -1)
- err.SetError(errno, DNBError::POSIX);
+ std::map<int, lldb_private::SocketAddress> sockets;
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ listen_host, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded("::socket ( domain = AF_INET, type = SOCK_STREAM, protocol "
- "= IPPROTO_TCP ) => socket = %i",
- listen_fd);
+ for (auto address : addresses) {
+ int sock_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
+ if (sock_fd == -1)
+ continue;
- if (err.Fail())
- return rnb_err;
+ SetSocketOption(sock_fd, SOL_SOCKET, SO_REUSEADDR, 1);
- // enable local address reuse
- SetSocketOption(listen_fd, SOL_SOCKET, SO_REUSEADDR, 1);
-
- struct sockaddr_in sa;
- ::memset(&sa, 0, sizeof sa);
- sa.sin_len = sizeof sa;
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
- sa.sin_addr.s_addr = INADDR_ANY; // Let incoming connections bind to any host
- // network interface (this is NOT who can
- // connect to us)
- int error = ::bind(listen_fd, (struct sockaddr *)&sa, sizeof(sa));
- if (error == -1)
- err.SetError(errno, DNBError::POSIX);
+ address.SetPort(port);
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded(
- "::bind ( socket = %i, (struct sockaddr *) &sa, sizeof(sa)) )",
- listen_fd);
+ int error = ::bind(sock_fd, &address.sockaddr(), address.GetLength());
+ if (error == -1) {
+ ClosePort(sock_fd, false);
+ continue;
+ }
- if (err.Fail()) {
- ClosePort(listen_fd, false);
- return rnb_err;
- }
+ error = ::listen(sock_fd, 5);
+ if (error == -1) {
+ ClosePort(sock_fd, false);
+ continue;
+ }
- error = ::listen(listen_fd, 5);
- if (error == -1)
- err.SetError(errno, DNBError::POSIX);
+ // We were asked to listen on port zero which means we must now read the
+ // actual port that was given to us as port zero is a special code for "find
+ // an open port for me". This will only execute on the first socket created,
+ // subesquent sockets will reuse this port number.
+ if (port == 0) {
+ socklen_t sa_len = address.GetLength();
+ if (getsockname(sock_fd, &address.sockaddr(), &sa_len) == 0)
+ port = address.GetPort();
+ }
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded("::listen ( socket = %i, backlog = 1 )", listen_fd);
+ sockets[sock_fd] = address;
+ }
- if (err.Fail()) {
- ClosePort(listen_fd, false);
+ if (sockets.size() == 0) {
+ err.SetError(errno, DNBError::POSIX);
+ err.LogThreaded("::listen or ::bind failed");
return rnb_err;
}
- if (callback) {
- // We were asked to listen on port zero which means we
- // must now read the actual port that was given to us
- // as port zero is a special code for "find an open port
- // for me".
- if (port == 0) {
- socklen_t sa_len = sizeof(sa);
- if (getsockname(listen_fd, (struct sockaddr *)&sa, &sa_len) == 0) {
- port = ntohs(sa.sin_port);
- callback(callback_baton, port);
- }
- } else {
- callback(callback_baton, port);
- }
- }
+ if (callback)
+ callback(callback_baton, port);
- struct sockaddr_in accept_addr;
- ::memset(&accept_addr, 0, sizeof accept_addr);
- accept_addr.sin_len = sizeof accept_addr;
+ std::vector<struct kevent> events;
+ events.resize(sockets.size());
+ int i = 0;
+ for (auto socket : sockets) {
+ EV_SET(&events[i++], socket.first, EVFILT_READ, EV_ADD, 0, 0, 0);
+ }
bool accept_connection = false;
// Loop until we are happy with our connection
while (!accept_connection) {
- socklen_t accept_addr_len = sizeof accept_addr;
- m_fd =
- ::accept(listen_fd, (struct sockaddr *)&accept_addr, &accept_addr_len);
- if (m_fd == -1)
- err.SetError(errno, DNBError::POSIX);
+ struct kevent event_list[4];
+ int num_events =
+ kevent(queue_id, events.data(), events.size(), event_list, 4, NULL);
- if (err.Fail() || DNBLogCheckLogBit(LOG_RNB_COMM))
- err.LogThreaded(
- "::accept ( socket = %i, address = %p, address_len = %u )", listen_fd,
- &accept_addr, accept_addr_len);
+ if (num_events < 0) {
+ err.SetError(errno, DNBError::MachKernel);
+ err.LogThreaded("error: kevent() failed.");
+ }
- if (err.Fail())
- break;
+ for (int i = 0; i < num_events; ++i) {
+ auto sock_fd = event_list[i].ident;
+ auto socket_pair = sockets.find(sock_fd);
+ if (socket_pair == sockets.end())
+ continue;
- if (listen_addr.sin_addr.s_addr == INADDR_ANY)
- accept_connection = true;
- else {
- if (accept_addr_len == listen_addr.sin_len &&
- accept_addr.sin_addr.s_addr == listen_addr.sin_addr.s_addr) {
+ lldb_private::SocketAddress &addr_in = socket_pair->second;
+ lldb_private::SocketAddress accept_addr;
+ socklen_t sa_len = accept_addr.GetMaxLength();
+ m_fd = ::accept(sock_fd, &accept_addr.sockaddr(), &sa_len);
+
+ if (m_fd == -1) {
+ err.SetError(errno, DNBError::POSIX);
+ err.LogThreaded("error: Socket accept failed.");
+ }
+
+ if (addr_in.IsAnyAddr())
accept_connection = true;
- } else {
- ::close(m_fd);
- m_fd = -1;
- const uint8_t *accept_ip =
- (const uint8_t *)&accept_addr.sin_addr.s_addr;
- const uint8_t *listen_ip =
- (const uint8_t *)&listen_addr.sin_addr.s_addr;
- ::fprintf(stderr, "error: rejecting incoming connection from "
- "%u.%u.%u.%u (expecting %u.%u.%u.%u)\n",
- accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
- listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
- DNBLogThreaded("error: rejecting connection from %u.%u.%u.%u "
- "(expecting %u.%u.%u.%u)",
- accept_ip[0], accept_ip[1], accept_ip[2], accept_ip[3],
- listen_ip[0], listen_ip[1], listen_ip[2], listen_ip[3]);
+ else {
+ if (accept_addr == addr_in)
+ accept_connection = true;
+ else {
+ ::close(m_fd);
+ m_fd = -1;
+ ::fprintf(
+ stderr,
+ "error: rejecting incoming connection from %s (expecting %s)\n",
+ accept_addr.GetIPAddress().c_str(),
+ addr_in.GetIPAddress().c_str());
+ DNBLogThreaded("error: rejecting connection from %s (expecting %s)\n",
+ accept_addr.GetIPAddress().c_str(),
+ addr_in.GetIPAddress().c_str());
+ }
}
}
+ if (err.Fail())
+ break;
+ }
+ for (auto socket : sockets) {
+ int ListenFd = socket.first;
+ ClosePort(ListenFd, false);
}
- ClosePort(listen_fd, false);
-
- if (err.Fail()) {
+ if (err.Fail())
return rnb_err;
- } else {
- // Keep our TCP packets coming without any delays.
- SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
- }
+
+ // Keep our TCP packets coming without any delays.
+ SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
return rnb_success;
}
rnb_err_t RNBSocket::Connect(const char *host, uint16_t port) {
+ auto result = rnb_err;
Disconnect(false);
- // Create the socket
- m_fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if (m_fd == -1)
- return rnb_err;
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ host, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
- // Enable local address reuse
- SetSocketOption(m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
+ for (auto address : addresses) {
+ m_fd = ::socket(address.GetFamily(), SOCK_STREAM, IPPROTO_TCP);
+ if (m_fd == -1)
+ continue;
- struct sockaddr_in sa;
- ::memset(&sa, 0, sizeof(sa));
- sa.sin_family = AF_INET;
- sa.sin_port = htons(port);
+ // Enable local address reuse
+ SetSocketOption(m_fd, SOL_SOCKET, SO_REUSEADDR, 1);
- if (!ResolveIPV4HostName(host, sa.sin_addr.s_addr)) {
- DNBLogThreaded("error: failed to resolve host '%s'", host);
- Disconnect(false);
- return rnb_err;
- }
+ address.SetPort(port);
- if (-1 == ::connect(m_fd, (const struct sockaddr *)&sa, sizeof(sa))) {
- Disconnect(false);
- return rnb_err;
- }
+ if (-1 == ::connect(m_fd, &address.sockaddr(), address.GetLength())) {
+ Disconnect(false);
+ continue;
+ }
+ SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
- // Keep our TCP packets coming without any delays.
- SetSocketOption(m_fd, IPPROTO_TCP, TCP_NODELAY, 1);
- return rnb_success;
+ result = rnb_success;
+ break;
+ }
+ return result;
}
rnb_err_t RNBSocket::useFD(int fd) {
diff --git a/tools/debugserver/source/debugserver.cpp b/tools/debugserver/source/debugserver.cpp
index 0cb72f4ece45..bc1954de334a 100644
--- a/tools/debugserver/source/debugserver.cpp
+++ b/tools/debugserver/source/debugserver.cpp
@@ -1345,10 +1345,18 @@ int main(int argc, char *argv[]) {
show_usage_and_exit(1);
}
// accept 'localhost:' prefix on port number
-
- int items_scanned = ::sscanf(argv[0], "%[^:]:%i", str, &port);
- if (items_scanned == 2) {
- host = str;
+ std::string host_specifier = argv[0];
+ auto colon_location = host_specifier.rfind(':');
+ if (colon_location != std::string::npos) {
+ host = host_specifier.substr(0, colon_location);
+ std::string port_str =
+ host_specifier.substr(colon_location + 1, std::string::npos);
+ char *end_ptr;
+ port = strtoul(port_str.c_str(), &end_ptr, 0);
+ if (end_ptr < port_str.c_str() + port_str.size())
+ show_usage_and_exit(2);
+ if (host.front() == '[' && host.back() == ']')
+ host = host.substr(1, host.size() - 2);
DNBLogDebug("host = '%s' port = %i", host.c_str(), port);
} else {
// No hostname means "localhost"
diff --git a/tools/lldb-server/Acceptor.cpp b/tools/lldb-server/Acceptor.cpp
index e6e73f8bdb6b..48a364886dc3 100644
--- a/tools/lldb-server/Acceptor.cpp
+++ b/tools/lldb-server/Acceptor.cpp
@@ -62,8 +62,7 @@ Error Acceptor::Listen(int backlog) {
Error Acceptor::Accept(const bool child_processes_inherit, Connection *&conn) {
Socket *conn_socket = nullptr;
- auto error = m_listener_socket_up->Accept(
- StringRef(m_name), child_processes_inherit, conn_socket);
+ auto error = m_listener_socket_up->Accept(conn_socket);
if (error.Success())
conn = new ConnectionFileDescriptor(conn_socket);
diff --git a/unittests/Host/SocketTest.cpp b/unittests/Host/SocketTest.cpp
index 7abb010a9089..eda3a11fc109 100644
--- a/unittests/Host/SocketTest.cpp
+++ b/unittests/Host/SocketTest.cpp
@@ -44,8 +44,7 @@ protected:
const char *listen_remote_address,
bool child_processes_inherit, Socket **accept_socket,
Error *error) {
- *error = listen_socket->Accept(listen_remote_address,
- child_processes_inherit, *accept_socket);
+ *error = listen_socket->Accept(*accept_socket);
}
template <typename SocketType>
@@ -56,7 +55,7 @@ protected:
bool child_processes_inherit = false;
Error error;
std::unique_ptr<SocketType> listen_socket_up(
- new SocketType(child_processes_inherit, error));
+ new SocketType(true, child_processes_inherit));
EXPECT_FALSE(error.Fail());
error = listen_socket_up->Listen(listen_remote_address, 5);
EXPECT_FALSE(error.Fail());
@@ -70,7 +69,7 @@ protected:
std::string connect_remote_address = get_connect_addr(*listen_socket_up);
std::unique_ptr<SocketType> connect_socket_up(
- new SocketType(child_processes_inherit, error));
+ new SocketType(true, child_processes_inherit));
EXPECT_FALSE(error.Fail());
error = connect_socket_up->Connect(connect_remote_address);
EXPECT_FALSE(error.Fail());
@@ -141,6 +140,20 @@ TEST_F(SocketTest, DecodeHostAndPort) {
EXPECT_STREQ("65535", port_str.c_str());
EXPECT_EQ(65535, port);
EXPECT_TRUE(error.Success());
+
+ EXPECT_TRUE(
+ Socket::DecodeHostAndPort("[::1]:12345", host_str, port_str, port, &error));
+ EXPECT_STREQ("::1", host_str.c_str());
+ EXPECT_STREQ("12345", port_str.c_str());
+ EXPECT_EQ(12345, port);
+ EXPECT_TRUE(error.Success());
+
+ EXPECT_TRUE(
+ Socket::DecodeHostAndPort("[abcd:12fg:AF58::1]:12345", host_str, port_str, port, &error));
+ EXPECT_STREQ("abcd:12fg:AF58::1", host_str.c_str());
+ EXPECT_STREQ("12345", port_str.c_str());
+ EXPECT_EQ(12345, port);
+ EXPECT_TRUE(error.Success());
}
#ifndef LLDB_DISABLE_POSIX
diff --git a/unittests/ObjectFile/ELF/CMakeLists.txt b/unittests/ObjectFile/ELF/CMakeLists.txt
index 4cae7ab2c0d6..a182f4a4244e 100644
--- a/unittests/ObjectFile/ELF/CMakeLists.txt
+++ b/unittests/ObjectFile/ELF/CMakeLists.txt
@@ -1,7 +1,17 @@
add_lldb_unittest(ObjectFileELFTests
TestELFHeader.cpp
+ TestObjectFileELF.cpp
LINK_LIBS
lldbPluginObjectFileELF
+ lldbPluginSymbolVendorELF
lldbCore
)
+
+add_dependencies(ObjectFileELFTests yaml2obj)
+add_definitions(-DYAML2OBJ="$<TARGET_FILE:yaml2obj>")
+
+set(test_inputs
+ sections-resolve-consistently.yaml
+ )
+add_unittest_inputs(ObjectFileELFTests "${test_inputs}")
diff --git a/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml b/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml
new file mode 100644
index 000000000000..98b68bd2773c
--- /dev/null
+++ b/unittests/ObjectFile/ELF/Inputs/sections-resolve-consistently.yaml
@@ -0,0 +1,50 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ Entry: 0x0000000000400180
+Sections:
+ - Name: .note.gnu.build-id
+ Type: SHT_NOTE
+ Flags: [ SHF_ALLOC ]
+ Address: 0x0000000000400158
+ AddressAlign: 0x0000000000000004
+ Content: 040000001400000003000000474E55003F3EC29E3FD83E49D18C4D49CD8A730CC13117B6
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x0000000000400180
+ AddressAlign: 0x0000000000000010
+ Content: 554889E58B042500106000890425041060005DC3
+ - Name: .data
+ Type: SHT_PROGBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000601000
+ AddressAlign: 0x0000000000000004
+ Content: 2F000000
+ - Name: .bss
+ Type: SHT_NOBITS
+ Flags: [ SHF_WRITE, SHF_ALLOC ]
+ Address: 0x0000000000601004
+ AddressAlign: 0x0000000000000004
+ Size: 0x0000000000000004
+Symbols:
+ Global:
+ - Name: Y
+ Type: STT_OBJECT
+ Section: .data
+ Value: 0x0000000000601000
+ Size: 0x0000000000000004
+ - Name: _start
+ Type: STT_FUNC
+ Section: .text
+ Value: 0x0000000000400180
+ Size: 0x0000000000000014
+ - Name: X
+ Type: STT_OBJECT
+ Section: .bss
+ Value: 0x0000000000601004
+ Size: 0x0000000000000004
+...
diff --git a/unittests/ObjectFile/ELF/TestObjectFileELF.cpp b/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
new file mode 100644
index 000000000000..6ed9b2357bb1
--- /dev/null
+++ b/unittests/ObjectFile/ELF/TestObjectFileELF.cpp
@@ -0,0 +1,105 @@
+//===-- TestObjectFileELF.cpp -----------------------------------*- C++ -*-===//
+//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Host/HostInfo.h"
+#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+
+#include "Plugins/SymbolVendor/ELF/SymbolVendorELF.h"
+
+extern const char *TestMainArgv0;
+
+using namespace lldb_private;
+using namespace lldb;
+
+class ObjectFileELFTest : public testing::Test {
+public:
+ void SetUp() override {
+ HostInfo::Initialize();
+ ObjectFileELF::Initialize();
+ SymbolVendorELF::Initialize();
+
+ m_inputs_folder = llvm::sys::path::parent_path(TestMainArgv0);
+ llvm::sys::path::append(m_inputs_folder, "Inputs");
+ llvm::sys::fs::make_absolute(m_inputs_folder);
+ }
+
+ void TearDown() override {
+ SymbolVendorELF::Terminate();
+ ObjectFileELF::Terminate();
+ HostInfo::Terminate();
+ }
+
+protected:
+ llvm::SmallString<128> m_inputs_folder;
+};
+
+#define ASSERT_NO_ERROR(x) \
+ if (std::error_code ASSERT_NO_ERROR_ec = x) { \
+ llvm::SmallString<128> MessageStorage; \
+ llvm::raw_svector_ostream Message(MessageStorage); \
+ Message << #x ": did not return errc::success.\n" \
+ << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n" \
+ << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n"; \
+ GTEST_FATAL_FAILURE_(MessageStorage.c_str()); \
+ } else { \
+ }
+
+TEST_F(ObjectFileELFTest, SectionsResolveConsistently) {
+ llvm::SmallString<128> yaml = m_inputs_folder;
+ llvm::sys::path::append(yaml, "sections-resolve-consistently.yaml");
+ llvm::SmallString<128> obj = m_inputs_folder;
+ ASSERT_NO_ERROR(llvm::sys::fs::createTemporaryFile(
+ "sections-resolve-consistently-%%%%%%", "obj", obj));
+
+ llvm::FileRemover remover(obj);
+ const char *args[] = {YAML2OBJ, yaml.c_str(), nullptr};
+ llvm::StringRef obj_ref = obj;
+ const llvm::StringRef *redirects[] = {nullptr, &obj_ref, nullptr};
+ ASSERT_EQ(0, llvm::sys::ExecuteAndWait(YAML2OBJ, args, nullptr, redirects));
+ uint64_t size;
+ ASSERT_NO_ERROR(llvm::sys::fs::file_size(obj, size));
+ ASSERT_GT(size, 0u);
+
+ ModuleSpec spec{FileSpec(obj, false)};
+ spec.GetSymbolFileSpec().SetFile(obj, false);
+ auto module_sp = std::make_shared<Module>(spec);
+ SectionList *list = module_sp->GetSectionList();
+ ASSERT_NE(nullptr, list);
+
+ auto bss_sp = list->FindSectionByName(ConstString(".bss"));
+ ASSERT_NE(nullptr, bss_sp);
+ auto data_sp = list->FindSectionByName(ConstString(".data"));
+ ASSERT_NE(nullptr, data_sp);
+ auto text_sp = list->FindSectionByName(ConstString(".text"));
+ ASSERT_NE(nullptr, text_sp);
+
+ const Symbol *X = module_sp->FindFirstSymbolWithNameAndType(ConstString("X"),
+ eSymbolTypeAny);
+ ASSERT_NE(nullptr, X);
+ EXPECT_EQ(bss_sp, X->GetAddress().GetSection());
+
+ const Symbol *Y = module_sp->FindFirstSymbolWithNameAndType(ConstString("Y"),
+ eSymbolTypeAny);
+ ASSERT_NE(nullptr, Y);
+ EXPECT_EQ(data_sp, Y->GetAddress().GetSection());
+
+ const Symbol *start = module_sp->FindFirstSymbolWithNameAndType(
+ ConstString("_start"), eSymbolTypeAny);
+ ASSERT_NE(nullptr, start);
+ EXPECT_EQ(text_sp, start->GetAddress().GetSection());
+}
diff --git a/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp b/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
index 08501f50f65a..6440e814efd4 100644
--- a/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
+++ b/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
@@ -33,15 +33,14 @@ void GDBRemoteTest::TearDownTestCase() {
void Connect(GDBRemoteCommunication &client, GDBRemoteCommunication &server) {
bool child_processes_inherit = false;
Error error;
- TCPSocket listen_socket(child_processes_inherit, error);
+ TCPSocket listen_socket(true, child_processes_inherit);
ASSERT_FALSE(error.Fail());
error = listen_socket.Listen("127.0.0.1:0", 5);
ASSERT_FALSE(error.Fail());
Socket *accept_socket;
std::future<Error> accept_error = std::async(std::launch::async, [&] {
- return listen_socket.Accept("127.0.0.1:0", child_processes_inherit,
- accept_socket);
+ return listen_socket.Accept(accept_socket);
});
char connect_remote_address[64];
diff --git a/unittests/debugserver/RNBSocketTest.cpp b/unittests/debugserver/RNBSocketTest.cpp
index 997041f6154b..76a1b49064f5 100644
--- a/unittests/debugserver/RNBSocketTest.cpp
+++ b/unittests/debugserver/RNBSocketTest.cpp
@@ -53,9 +53,21 @@ static void ServerCallbackv4(const void *baton, in_port_t port) {
}
void TestSocketListen(const char *addr) {
+ // Skip IPv6 tests if there isn't a valid interafce
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ if (addresses.size() == 0)
+ return;
+
+ char addr_wrap[256];
+ if (addresses.front().GetFamily() == AF_INET6)
+ sprintf(addr_wrap, "[%s]", addr);
+ else
+ sprintf(addr_wrap, "%s", addr);
+
RNBSocket server_socket;
auto result =
- server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr);
+ server_socket.Listen(addr, 0, ServerCallbackv4, (const void *)addr_wrap);
ASSERT_TRUE(result == rnb_success);
result = server_socket.Write(hello.c_str(), hello.length());
ASSERT_TRUE(result == rnb_success);
@@ -71,9 +83,20 @@ void TestSocketListen(const char *addr) {
TEST(RNBSocket, LoopBackListenIPv4) { TestSocketListen("127.0.0.1"); }
+TEST(RNBSocket, LoopBackListenIPv6) { TestSocketListen("::1"); }
+
void TestSocketConnect(const char *addr) {
+ // Skip IPv6 tests if there isn't a valid interafce
+ auto addresses = lldb_private::SocketAddress::GetAddressInfo(
+ addr, NULL, AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
+ if (addresses.size() == 0)
+ return;
+
char addr_wrap[256];
- sprintf(addr_wrap, "%s:0", addr);
+ if (addresses.front().GetFamily() == AF_INET6)
+ sprintf(addr_wrap, "[%s]:0", addr);
+ else
+ sprintf(addr_wrap, "%s:0", addr);
Socket *server_socket;
Predicate<uint16_t> port_predicate;
@@ -96,7 +119,7 @@ void TestSocketConnect(const char *addr) {
ASSERT_EQ(bye, goodbye);
} else {
Socket *connected_socket;
- err = server_socket->Accept(addr_wrap, false, connected_socket);
+ err = server_socket->Accept(connected_socket);
if (err.Fail()) {
llvm::errs() << err.AsCString();
abort();
@@ -131,3 +154,5 @@ void TestSocketConnect(const char *addr) {
}
TEST(RNBSocket, LoopBackConnectIPv4) { TestSocketConnect("127.0.0.1"); }
+
+TEST(RNBSocket, LoopBackConnectIPv6) { TestSocketConnect("::1"); }