1//===-- ProcessMessage.h ----------------------------------------*- 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#ifndef liblldb_ProcessMessage_H_
11#define liblldb_ProcessMessage_H_
12
13#include <cassert>
14
15#include "lldb/lldb-defines.h"
16#include "lldb/lldb-types.h"
17
18class ProcessMessage
19{
20public:
21
22    /// The type of signal this message can correspond to.
23    enum Kind
24    {
25        eInvalidMessage,
26        eExitMessage,
27        eLimboMessage,
28        eSignalMessage,
29        eSignalDeliveredMessage,
30        eTraceMessage,
31        eBreakpointMessage,
32        eWatchpointMessage,
33        eCrashMessage,
34        eNewThreadMessage
35    };
36
37    enum CrashReason
38    {
39        eInvalidCrashReason,
40
41        // SIGSEGV crash reasons.
42        eInvalidAddress,
43        ePrivilegedAddress,
44
45        // SIGILL crash reasons.
46        eIllegalOpcode,
47        eIllegalOperand,
48        eIllegalAddressingMode,
49        eIllegalTrap,
50        ePrivilegedOpcode,
51        ePrivilegedRegister,
52        eCoprocessorError,
53        eInternalStackError,
54
55        // SIGBUS crash reasons,
56        eIllegalAlignment,
57        eIllegalAddress,
58        eHardwareError,
59
60        // SIGFPE crash reasons,
61        eIntegerDivideByZero,
62        eIntegerOverflow,
63        eFloatDivideByZero,
64        eFloatOverflow,
65        eFloatUnderflow,
66        eFloatInexactResult,
67        eFloatInvalidOperation,
68        eFloatSubscriptRange
69    };
70
71    ProcessMessage()
72        : m_tid(LLDB_INVALID_PROCESS_ID),
73          m_kind(eInvalidMessage),
74          m_crash_reason(eInvalidCrashReason),
75          m_status(0),
76          m_addr(0) { }
77
78    Kind GetKind() const { return m_kind; }
79
80    lldb::tid_t GetTID() const { return m_tid; }
81
82    /// Indicates that the thread @p tid is about to exit with status @p status.
83    static ProcessMessage Limbo(lldb::tid_t tid, int status) {
84        return ProcessMessage(tid, eLimboMessage, status);
85    }
86
87    /// Indicates that the thread @p tid had the signal @p signum delivered.
88    static ProcessMessage Signal(lldb::tid_t tid, int signum) {
89        return ProcessMessage(tid, eSignalMessage, signum);
90    }
91
92    /// Indicates that a signal @p signum generated by the debugging process was
93    /// delivered to the thread @p tid.
94    static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) {
95        return ProcessMessage(tid, eSignalDeliveredMessage, signum);
96    }
97
98    /// Indicates that the thread @p tid encountered a trace point.
99    static ProcessMessage Trace(lldb::tid_t tid) {
100        return ProcessMessage(tid, eTraceMessage);
101    }
102
103    /// Indicates that the thread @p tid encountered a break point.
104    static ProcessMessage Break(lldb::tid_t tid) {
105        return ProcessMessage(tid, eBreakpointMessage);
106    }
107
108    static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) {
109        return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr);
110    }
111
112    /// Indicates that the thread @p tid crashed.
113    static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason,
114                                int signo, lldb::addr_t fault_addr) {
115        ProcessMessage message(pid, eCrashMessage, signo, fault_addr);
116        message.m_crash_reason = reason;
117        return message;
118    }
119
120    /// Indicates that the thread @p child_tid was spawned.
121    static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
122        return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
123    }
124
125    /// Indicates that the thread @p tid is about to exit with status @p status.
126    static ProcessMessage Exit(lldb::tid_t tid, int status) {
127        return ProcessMessage(tid, eExitMessage, status);
128    }
129
130    int GetExitStatus() const {
131        assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
132        return m_status;
133    }
134
135    int GetSignal() const {
136        assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage ||
137               GetKind() == eSignalDeliveredMessage);
138        return m_status;
139    }
140
141    int GetStopStatus() const {
142        assert(GetKind() == eSignalMessage);
143        return m_status;
144    }
145
146    CrashReason GetCrashReason() const {
147        assert(GetKind() == eCrashMessage);
148        return m_crash_reason;
149    }
150
151    lldb::addr_t GetFaultAddress() const {
152        assert(GetKind() == eCrashMessage);
153        return m_addr;
154    }
155
156    lldb::addr_t GetHWAddress() const {
157        assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage);
158        return m_addr;
159    }
160
161    lldb::tid_t GetChildTID() const {
162        assert(GetKind() == eNewThreadMessage);
163        return m_child_tid;
164    }
165
166    static const char *
167    GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr);
168
169    const char *
170    PrintCrashReason() const;
171
172    static const char *
173    PrintCrashReason(CrashReason reason);
174
175    const char *
176    PrintKind() const;
177
178    static const char *
179    PrintKind(Kind);
180
181private:
182    ProcessMessage(lldb::tid_t tid, Kind kind,
183                   int status = 0, lldb::addr_t addr = 0)
184        : m_tid(tid),
185          m_kind(kind),
186          m_crash_reason(eInvalidCrashReason),
187          m_status(status),
188          m_addr(addr),
189          m_child_tid(0) { }
190
191    ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
192        : m_tid(tid),
193          m_kind(kind),
194          m_crash_reason(eInvalidCrashReason),
195          m_status(0),
196          m_addr(0),
197          m_child_tid(child_tid) { }
198
199    lldb::tid_t m_tid;
200    Kind        m_kind         : 8;
201    CrashReason m_crash_reason : 8;
202    int m_status;
203    lldb::addr_t m_addr;
204    lldb::tid_t m_child_tid;
205};
206
207#endif // #ifndef liblldb_ProcessMessage_H_
208