124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- MachException.h -----------------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  Created by Greg Clayton on 6/18/07.
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#ifndef __MachException_h__
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#define __MachException_h__
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <mach/mach.h>
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <vector>
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DNBConfig.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass MachProcess;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass PThreadMutex;
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnertypedef union MachMessageTag
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    mach_msg_header_t hdr;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    char data[1024];
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner} MachMessage;
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass MachException
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct PortInfo
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
384402f7032005918e5f879234a078a7a265495a6bGreg Clayton        exception_mask_t        mask; // the exception mask for this device which may be a subset of EXC_MASK_ALL...
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exception_mask_t        masks[EXC_TYPES_COUNT];
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        mach_port_t             ports[EXC_TYPES_COUNT];
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exception_behavior_t    behaviors[EXC_TYPES_COUNT];
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        thread_state_flavor_t   flavors[EXC_TYPES_COUNT];
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        mach_msg_type_number_t  count;
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t   Save(task_t task);
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t   Restore(task_t task);
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct Data
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        task_t task_port;
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        thread_t thread_port;
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exception_type_t exc_type;
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<mach_exception_data_type_t> exc_data;
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Data() :
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            task_port(TASK_NULL),
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            thread_port(THREAD_NULL),
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exc_type(0),
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exc_data()
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void Clear()
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            task_port = TASK_NULL;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            thread_port = THREAD_NULL;
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exc_type = 0;
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            exc_data.clear();
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool IsValid() const
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return  task_port != TASK_NULL &&
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    thread_port != THREAD_NULL &&
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                    exc_type != 0;
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        // Return the SoftSignal for this MachException data, or zero if there is none
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        int SoftSignal() const
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (exc_type == EXC_SOFTWARE && exc_data.size() == 2 && exc_data[0] == EXC_SOFT_SIGNAL)
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return exc_data[1];
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return 0;
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool IsBreakpoint() const
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return (exc_type == EXC_BREAKPOINT) || ((exc_type == EXC_SOFTWARE) && exc_data[0] == 1);
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void Dump() const;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void DumpStopReason() const;
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        bool GetStopInfo(struct DNBThreadStopInfo *stop_info) const;
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct Message
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        MachMessage exc_msg;
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        MachMessage reply_msg;
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Data state;
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Message() :
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            state()
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            memset(&exc_msg,   0, sizeof(exc_msg));
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            memset(&reply_msg, 0, sizeof(reply_msg));
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
104ad7bd23aab27a769aea2266e66ad36bfc0d6e86dGreg Clayton        bool CatchExceptionRaise(task_t task);
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        void Dump() const;
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t Reply (MachProcess *process, int signal);
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        kern_return_t Receive( mach_port_t receive_port,
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                               mach_msg_option_t options,
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                               mach_msg_timeout_t timeout,
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                               mach_port_t notify_port = MACH_PORT_NULL);
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef std::vector<Message>        collection;
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef collection::iterator        iterator;
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef collection::const_iterator    const_iterator;
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    enum
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_actionForward,    // Forward signal to inferior process
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        e_actionStop,        // Stop when this signal is received
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    struct Action
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        task_t task_port;            // Set to TASK_NULL for any TASK
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        thread_t thread_port;        // Set to THREAD_NULL for any thread
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        exception_type_t exc_mask;    // Mach exception mask to watch for
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<mach_exception_data_type_t> exc_data_mask;    // Mask to apply to exception data, or empty to ignore exc_data value for exception
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        std::vector<mach_exception_data_type_t> exc_data_value;    // Value to compare to exception data after masking, or empty to ignore exc_data value for exception
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint8_t flags;                // Action flags describing what to do with the exception
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    };
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    static const char *Name(exception_type_t exc_type);
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#endif
135