Refactor Unix signals.

Summary:
- Consolidate Unix signals selection in UnixSignals.
- Make Unix signals available from platform.
- Add jSignalsInfo packet to retrieve Unix signals from remote platform.
- Get a copy of the platform signal for each remote process.
- Update SB API for signals.
- Update signal utility in test suite.

Reviewers: ovyalov, clayborg

Subscribers: chaoren, jingham, labath, emaste, tberghammer, lldb-commits

Differential Revision: http://reviews.llvm.org/D11094

llvm-svn: 242101
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index afc772d..2a253c5 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -1056,8 +1056,8 @@
     // may change if we are interrupted and we continue after an async packet...
     std::string continue_packet(payload, packet_length);
 
-    const auto sigstop_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGSTOP");
-    const auto sigint_signo = process->GetUnixSignals().GetSignalNumberFromName("SIGINT");
+    const auto sigstop_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGSTOP");
+    const auto sigint_signo = process->GetUnixSignals()->GetSignalNumberFromName("SIGINT");
 
     bool got_async_packet = false;
     
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
index f5e5d76..1205049 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp
@@ -19,6 +19,7 @@
 // Other libraries and framework includes
 #include "lldb/Core/Log.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/StructuredData.h"
 #include "lldb/Host/Config.h"
 #include "lldb/Host/ConnectionFileDescriptor.h"
 #include "lldb/Host/Host.h"
@@ -26,6 +27,7 @@
 #include "lldb/Target/FileAction.h"
 #include "lldb/Target/Platform.h"
 #include "lldb/Target/Process.h"
+#include "lldb/Target/UnixSignals.h"
 
 // Project includes
 #include "Utility/StringExtractorGDBRemote.h"
@@ -54,6 +56,8 @@
                                   &GDBRemoteCommunicationServerPlatform::Handle_qProcessInfo);
     RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
                                   &GDBRemoteCommunicationServerPlatform::Handle_QSetWorkingDir);
+    RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_jSignalsInfo,
+                                  &GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo);
 
     RegisterPacketHandler(StringExtractorGDBRemote::eServerPacketType_interrupt,
                           [this](StringExtractorGDBRemote packet,
@@ -251,6 +255,35 @@
     return SendPacketNoLock (response.GetData(), response.GetSize());
 }
 
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServerPlatform::Handle_jSignalsInfo(StringExtractorGDBRemote &packet)
+{
+    StructuredData::Array signal_array;
+
+    const auto &signals = Host::GetUnixSignals();
+    for (auto signo = signals->GetFirstSignalNumber();
+         signo != LLDB_INVALID_SIGNAL_NUMBER;
+         signo = signals->GetNextSignalNumber(signo))
+    {
+        auto dictionary = std::make_shared<StructuredData::Dictionary>();
+
+        dictionary->AddIntegerItem("signo", signo);
+        dictionary->AddStringItem("name", signals->GetSignalAsCString(signo));
+
+        bool suppress, stop, notify;
+        signals->GetSignalInfo(signo, suppress, stop, notify);
+        dictionary->AddBooleanItem("suppress", suppress);
+        dictionary->AddBooleanItem("stop", stop);
+        dictionary->AddBooleanItem("notify", notify);
+
+        signal_array.Push(dictionary);
+    }
+
+    StreamString response;
+    signal_array.Dump(response);
+    return SendPacketNoLock(response.GetData(), response.GetSize());
+}
+
 bool
 GDBRemoteCommunicationServerPlatform::DebugserverProcessReaped (lldb::pid_t pid)
 {
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
index 4124b04..5c01137 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h
@@ -79,6 +79,9 @@
     PacketResult
     Handle_qC (StringExtractorGDBRemote &packet);
 
+    PacketResult
+    Handle_jSignalsInfo(StringExtractorGDBRemote &packet);
+
 private:
     bool
     DebugserverProcessReaped (lldb::pid_t pid);
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index ef79e08..0bcc8ca 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -65,10 +65,8 @@
 
 // Project includes
 #include "lldb/Host/Host.h"
-#include "Plugins/Process/Utility/FreeBSDSignals.h"
+#include "Plugins/Process/Utility/GDBRemoteSignals.h"
 #include "Plugins/Process/Utility/InferiorCallPOSIX.h"
-#include "Plugins/Process/Utility/LinuxSignals.h"
-#include "Plugins/Process/Utility/MipsLinuxSignals.h"
 #include "Plugins/Process/Utility/StopInfoMachException.h"
 #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h"
 #include "Utility/StringExtractorGDBRemote.h"
@@ -823,41 +821,8 @@
     if (log)
         log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": normalized target architecture triple: %s", __FUNCTION__, GetID (), GetTarget ().GetArchitecture ().GetTriple ().getTriple ().c_str ());
 
-    // Set the Unix signals properly for the target.
-    // FIXME Add a gdb-remote packet to discover dynamically.
-    if (error.Success ())
-    {
-        const ArchSpec arch_spec = m_gdb_comm.GetHostArchitecture();
-        if (arch_spec.IsValid ())
-        {
-            if (log)
-                log->Printf ("ProcessGDBRemote::%s pid %" PRIu64 ": determining unix signals type based on architecture %s, triple %s", __FUNCTION__, GetID (), arch_spec.GetArchitectureName () ? arch_spec.GetArchitectureName () : "<null>", arch_spec.GetTriple ().getTriple ().c_str ());
-
-            switch (arch_spec.GetTriple ().getOS ())
-            {
-            case llvm::Triple::Linux:
-                if (arch_spec.GetTriple ().getArch () == llvm::Triple::mips64 || arch_spec.GetTriple ().getArch () == llvm::Triple::mips64el)
-                    SetUnixSignals (UnixSignalsSP (new process_linux::MipsLinuxSignals ()));
-                else
-                    SetUnixSignals (UnixSignalsSP (new process_linux::LinuxSignals ()));
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s using Linux unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
-                break;
-            case llvm::Triple::OpenBSD:
-            case llvm::Triple::FreeBSD:
-            case llvm::Triple::NetBSD:
-                SetUnixSignals (UnixSignalsSP (new FreeBSDSignals ()));
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s using *BSD unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
-                break;
-            default:
-                SetUnixSignals (UnixSignalsSP (new UnixSignals ()));
-                if (log)
-                    log->Printf ("ProcessGDBRemote::%s using generic unix signals type for pid %" PRIu64, __FUNCTION__, GetID ());
-                break;
-            }
-        }
-    }
+    if (error.Success())
+        SetUnixSignals(std::make_shared<GDBRemoteSignals>(GetTarget().GetPlatform()->GetUnixSignals()));
 
     return error;
 }
@@ -3524,7 +3489,7 @@
                 char error_str[1024];
                 if (signo)
                 {
-                    const char *signal_cstr = process->GetUnixSignals().GetSignalAsCString (signo);
+                    const char *signal_cstr = process->GetUnixSignals()->GetSignalAsCString(signo);
                     if (signal_cstr)
                         ::snprintf (error_str, sizeof (error_str), DEBUGSERVER_BASENAME " died with signal %s", signal_cstr);
                     else
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index 59c701d..d2a6503 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -215,14 +215,14 @@
             break;
 
         case eStateRunning:
-            if (gdb_process->GetUnixSignals().SignalIsValid (signo))
+            if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
                 gdb_process->m_continue_C_tids.push_back(std::make_pair(tid, signo));
             else
                 gdb_process->m_continue_c_tids.push_back(tid);
             break;
 
         case eStateStepping:
-            if (gdb_process->GetUnixSignals().SignalIsValid (signo))
+            if (gdb_process->GetUnixSignals()->SignalIsValid(signo))
                 gdb_process->m_continue_S_tids.push_back(std::make_pair(tid, signo));
             else
                 gdb_process->m_continue_s_tids.push_back(tid);