]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp
MFV r315791: ntp 4.2.8p10.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Target / UnixSignals.cpp
1 //===-- UnixSignals.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "lldb/Target/UnixSignals.h"
15 #include "Plugins/Process/Utility/FreeBSDSignals.h"
16 #include "Plugins/Process/Utility/LinuxSignals.h"
17 #include "Plugins/Process/Utility/MipsLinuxSignals.h"
18 #include "Plugins/Process/Utility/NetBSDSignals.h"
19 #include "lldb/Core/ArchSpec.h"
20 #include "lldb/Host/StringConvert.h"
21
22 using namespace lldb_private;
23
24 UnixSignals::Signal::Signal(const char *name, bool default_suppress,
25                             bool default_stop, bool default_notify,
26                             const char *description, const char *alias)
27     : m_name(name), m_alias(alias), m_description(),
28       m_suppress(default_suppress), m_stop(default_stop),
29       m_notify(default_notify) {
30   if (description)
31     m_description.assign(description);
32 }
33
34 lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) {
35   const auto &triple = arch.GetTriple();
36   switch (triple.getOS()) {
37   case llvm::Triple::Linux: {
38     switch (triple.getArch()) {
39     case llvm::Triple::mips:
40     case llvm::Triple::mipsel:
41     case llvm::Triple::mips64:
42     case llvm::Triple::mips64el:
43       return std::make_shared<MipsLinuxSignals>();
44     default:
45       return std::make_shared<LinuxSignals>();
46     }
47   }
48   case llvm::Triple::FreeBSD:
49   case llvm::Triple::OpenBSD:
50     return std::make_shared<FreeBSDSignals>();
51   case llvm::Triple::NetBSD:
52     return std::make_shared<NetBSDSignals>();
53   default:
54     return std::make_shared<UnixSignals>();
55   }
56 }
57
58 //----------------------------------------------------------------------
59 // UnixSignals constructor
60 //----------------------------------------------------------------------
61 UnixSignals::UnixSignals() { Reset(); }
62
63 UnixSignals::UnixSignals(const UnixSignals &rhs) : m_signals(rhs.m_signals) {}
64
65 UnixSignals::~UnixSignals() = default;
66
67 void UnixSignals::Reset() {
68   // This builds one standard set of Unix Signals.  If yours aren't quite in
69   // this
70   // order, you can either subclass this class, and use Add & Remove to change
71   // them
72   // or you can subclass and build them afresh in your constructor;
73   //
74   // Note: the signals below are the Darwin signals.  Do not change these!
75   m_signals.clear();
76   //        SIGNO  NAME          SUPPRESS STOP   NOTIFY DESCRIPTION
77   //        ====== ============  ======== ====== ======
78   //        ===================================================
79   AddSignal(1, "SIGHUP", false, true, true, "hangup");
80   AddSignal(2, "SIGINT", true, true, true, "interrupt");
81   AddSignal(3, "SIGQUIT", false, true, true, "quit");
82   AddSignal(4, "SIGILL", false, true, true, "illegal instruction");
83   AddSignal(5, "SIGTRAP", true, true, true,
84             "trace trap (not reset when caught)");
85   AddSignal(6, "SIGABRT", false, true, true, "abort()");
86   AddSignal(7, "SIGEMT", false, true, true, "pollable event");
87   AddSignal(8, "SIGFPE", false, true, true, "floating point exception");
88   AddSignal(9, "SIGKILL", false, true, true, "kill");
89   AddSignal(10, "SIGBUS", false, true, true, "bus error");
90   AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation");
91   AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call");
92   AddSignal(13, "SIGPIPE", false, true, true,
93             "write on a pipe with no one to read it");
94   AddSignal(14, "SIGALRM", false, false, false, "alarm clock");
95   AddSignal(15, "SIGTERM", false, true, true,
96             "software termination signal from kill");
97   AddSignal(16, "SIGURG", false, false, false,
98             "urgent condition on IO channel");
99   AddSignal(17, "SIGSTOP", true, true, true,
100             "sendable stop signal not from tty");
101   AddSignal(18, "SIGTSTP", false, true, true, "stop signal from tty");
102   AddSignal(19, "SIGCONT", false, true, true, "continue a stopped process");
103   AddSignal(20, "SIGCHLD", false, false, false,
104             "to parent on child stop or exit");
105   AddSignal(21, "SIGTTIN", false, true, true,
106             "to readers process group upon background tty read");
107   AddSignal(22, "SIGTTOU", false, true, true,
108             "to readers process group upon background tty write");
109   AddSignal(23, "SIGIO", false, false, false, "input/output possible signal");
110   AddSignal(24, "SIGXCPU", false, true, true, "exceeded CPU time limit");
111   AddSignal(25, "SIGXFSZ", false, true, true, "exceeded file size limit");
112   AddSignal(26, "SIGVTALRM", false, false, false, "virtual time alarm");
113   AddSignal(27, "SIGPROF", false, false, false, "profiling time alarm");
114   AddSignal(28, "SIGWINCH", false, false, false, "window size changes");
115   AddSignal(29, "SIGINFO", false, true, true, "information request");
116   AddSignal(30, "SIGUSR1", false, true, true, "user defined signal 1");
117   AddSignal(31, "SIGUSR2", false, true, true, "user defined signal 2");
118 }
119
120 void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress,
121                             bool default_stop, bool default_notify,
122                             const char *description, const char *alias) {
123   Signal new_signal(name, default_suppress, default_stop, default_notify,
124                     description, alias);
125   m_signals.insert(std::make_pair(signo, new_signal));
126 }
127
128 void UnixSignals::RemoveSignal(int signo) {
129   collection::iterator pos = m_signals.find(signo);
130   if (pos != m_signals.end())
131     m_signals.erase(pos);
132 }
133
134 const char *UnixSignals::GetSignalAsCString(int signo) const {
135   collection::const_iterator pos = m_signals.find(signo);
136   if (pos == m_signals.end())
137     return nullptr;
138   else
139     return pos->second.m_name.GetCString();
140 }
141
142 bool UnixSignals::SignalIsValid(int32_t signo) const {
143   return m_signals.find(signo) != m_signals.end();
144 }
145
146 ConstString UnixSignals::GetShortName(ConstString name) const {
147   if (name) {
148     const char *signame = name.AsCString();
149     return ConstString(signame + 3); // Remove "SIG" from name
150   }
151   return name;
152 }
153
154 int32_t UnixSignals::GetSignalNumberFromName(const char *name) const {
155   ConstString const_name(name);
156
157   collection::const_iterator pos, end = m_signals.end();
158   for (pos = m_signals.begin(); pos != end; pos++) {
159     if ((const_name == pos->second.m_name) ||
160         (const_name == pos->second.m_alias) ||
161         (const_name == GetShortName(pos->second.m_name)) ||
162         (const_name == GetShortName(pos->second.m_alias)))
163       return pos->first;
164   }
165
166   const int32_t signo =
167       StringConvert::ToSInt32(name, LLDB_INVALID_SIGNAL_NUMBER, 0);
168   if (signo != LLDB_INVALID_SIGNAL_NUMBER)
169     return signo;
170   return LLDB_INVALID_SIGNAL_NUMBER;
171 }
172
173 int32_t UnixSignals::GetFirstSignalNumber() const {
174   if (m_signals.empty())
175     return LLDB_INVALID_SIGNAL_NUMBER;
176
177   return (*m_signals.begin()).first;
178 }
179
180 int32_t UnixSignals::GetNextSignalNumber(int32_t current_signal) const {
181   collection::const_iterator pos = m_signals.find(current_signal);
182   collection::const_iterator end = m_signals.end();
183   if (pos == end)
184     return LLDB_INVALID_SIGNAL_NUMBER;
185   else {
186     pos++;
187     if (pos == end)
188       return LLDB_INVALID_SIGNAL_NUMBER;
189     else
190       return pos->first;
191   }
192 }
193
194 const char *UnixSignals::GetSignalInfo(int32_t signo, bool &should_suppress,
195                                        bool &should_stop,
196                                        bool &should_notify) const {
197   collection::const_iterator pos = m_signals.find(signo);
198   if (pos == m_signals.end())
199     return nullptr;
200   else {
201     const Signal &signal = pos->second;
202     should_suppress = signal.m_suppress;
203     should_stop = signal.m_stop;
204     should_notify = signal.m_notify;
205     return signal.m_name.AsCString("");
206   }
207 }
208
209 bool UnixSignals::GetShouldSuppress(int signo) const {
210   collection::const_iterator pos = m_signals.find(signo);
211   if (pos != m_signals.end())
212     return pos->second.m_suppress;
213   return false;
214 }
215
216 bool UnixSignals::SetShouldSuppress(int signo, bool value) {
217   collection::iterator pos = m_signals.find(signo);
218   if (pos != m_signals.end()) {
219     pos->second.m_suppress = value;
220     return true;
221   }
222   return false;
223 }
224
225 bool UnixSignals::SetShouldSuppress(const char *signal_name, bool value) {
226   const int32_t signo = GetSignalNumberFromName(signal_name);
227   if (signo != LLDB_INVALID_SIGNAL_NUMBER)
228     return SetShouldSuppress(signo, value);
229   return false;
230 }
231
232 bool UnixSignals::GetShouldStop(int signo) const {
233   collection::const_iterator pos = m_signals.find(signo);
234   if (pos != m_signals.end())
235     return pos->second.m_stop;
236   return false;
237 }
238
239 bool UnixSignals::SetShouldStop(int signo, bool value) {
240   collection::iterator pos = m_signals.find(signo);
241   if (pos != m_signals.end()) {
242     pos->second.m_stop = value;
243     return true;
244   }
245   return false;
246 }
247
248 bool UnixSignals::SetShouldStop(const char *signal_name, bool value) {
249   const int32_t signo = GetSignalNumberFromName(signal_name);
250   if (signo != LLDB_INVALID_SIGNAL_NUMBER)
251     return SetShouldStop(signo, value);
252   return false;
253 }
254
255 bool UnixSignals::GetShouldNotify(int signo) const {
256   collection::const_iterator pos = m_signals.find(signo);
257   if (pos != m_signals.end())
258     return pos->second.m_notify;
259   return false;
260 }
261
262 bool UnixSignals::SetShouldNotify(int signo, bool value) {
263   collection::iterator pos = m_signals.find(signo);
264   if (pos != m_signals.end()) {
265     pos->second.m_notify = value;
266     return true;
267   }
268   return false;
269 }
270
271 bool UnixSignals::SetShouldNotify(const char *signal_name, bool value) {
272   const int32_t signo = GetSignalNumberFromName(signal_name);
273   if (signo != LLDB_INVALID_SIGNAL_NUMBER)
274     return SetShouldNotify(signo, value);
275   return false;
276 }
277
278 int32_t UnixSignals::GetNumSignals() const { return m_signals.size(); }
279
280 int32_t UnixSignals::GetSignalAtIndex(int32_t index) const {
281   if (index < 0 || m_signals.size() <= static_cast<size_t>(index))
282     return LLDB_INVALID_SIGNAL_NUMBER;
283   auto it = m_signals.begin();
284   std::advance(it, index);
285   return it->first;
286 }