aboutsummaryrefslogtreecommitdiff
path: root/gdb/darwin-nat.h
blob: 0eacb5530d30b885bdf8a5ab9ee707e05b24913b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* Common things used by the various darwin files
   Copyright (C) 1995-2018 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef __DARWIN_NAT_H__
#define __DARWIN_NAT_H__

#include <mach/mach.h>
#include "gdbthread.h"

/* Describe the mach exception handling state for a task.  This state is saved
   before being changed and restored when a process is detached.
   For more information on these fields see task_get_exception_ports manual
   page.  */
struct darwin_exception_info
{
  /* Exceptions handled by the port.  */
  exception_mask_t masks[EXC_TYPES_COUNT] {};

  /* Ports receiving exception messages.  */
  mach_port_t ports[EXC_TYPES_COUNT] {};

  /* Type of messages sent.  */
  exception_behavior_t behaviors[EXC_TYPES_COUNT] {};

  /* Type of state to be sent.  */
  thread_state_flavor_t flavors[EXC_TYPES_COUNT] {};

  /* Number of elements set.  */
  mach_msg_type_number_t count = 0;
};

struct darwin_exception_msg
{
  mach_msg_header_t header;

  /* Thread and task taking the exception.  */
  mach_port_t thread_port;
  mach_port_t task_port;

  /* Type of the exception.  */
  exception_type_t ex_type;

  /* Machine dependent details.  */
  mach_msg_type_number_t data_count;
  integer_t ex_data[2];
};

enum darwin_msg_state
{
  /* The thread is running.  */
  DARWIN_RUNNING,

  /* The thread is stopped.  */
  DARWIN_STOPPED,

  /* The thread has sent a message and waits for a reply.  */
  DARWIN_MESSAGE
};

struct darwin_thread_info : public private_thread_info
{
  /* The thread port from a GDB point of view.  */
  thread_t gdb_port;

  /* The thread port from the inferior point of view.  Not to be used inside
     gdb except for get_ada_task_ptid.  */
  thread_t inf_port;

  /* Current message state.
     If the kernel has sent a message it expects a reply and the inferior
     can't be killed before.  */
  enum darwin_msg_state msg_state;

  /* True if this thread is single-stepped.  */
  unsigned char single_step;

  /* True if a signal was manually sent to the thread.  */
  unsigned char signaled;

  /* The last exception received.  */
  struct darwin_exception_msg event;
};
typedef struct darwin_thread_info darwin_thread_t;

static inline darwin_thread_info *
get_darwin_thread_info (class thread_info *thread)
{
  return static_cast<darwin_thread_info *> (thread->priv.get ());
}

/* Describe an inferior.  */
struct darwin_inferior : public private_inferior
{
  /* Corresponding task port.  */
  task_t task = 0;

  /* Port which will receive the dead-name notification for the task port.
     This is used to detect the death of the task.  */
  mach_port_t notify_port = 0;

  /* Initial exception handling.  */
  darwin_exception_info exception_info;

  /* Number of messages that have been received but not yet replied.  */
  unsigned int pending_messages = 0;

  /* Set if inferior is not controlled by ptrace(2) but through Mach.  */
  bool no_ptrace = false;

  /* True if this task is suspended.  */
  bool suspended = false;

  /* Sorted vector of known threads.  */
  std::vector<darwin_thread_t *> threads;
};

/* Return the darwin_inferior attached to INF.  */

static inline darwin_inferior *
get_darwin_inferior (inferior *inf)
{
  return static_cast<darwin_inferior *> (inf->priv.get ());
}

/* Exception port.  */
extern mach_port_t darwin_ex_port;

/* Port set.  */
extern mach_port_t darwin_port_set;

/* A copy of mach_host_self ().  */
extern mach_port_t darwin_host_self;

/* FUNCTION_NAME is defined in common-utils.h (or not).  */
#ifdef FUNCTION_NAME
#define MACH_CHECK_ERROR(ret) \
  mach_check_error (ret, __FILE__, __LINE__, FUNCTION_NAME)
#else
#define MACH_CHECK_ERROR(ret) \
  mach_check_error (ret, __FILE__, __LINE__, "??")
#endif

extern void mach_check_error (kern_return_t ret, const char *file,
			      unsigned int line, const char *func);

void darwin_set_sstep (thread_t thread, int enable);

/* This one is called in darwin-nat.c, but needs to be provided by the
   platform specific nat code.  It allows each platform to add platform specific
   stuff to the darwin_ops.  */
extern void darwin_complete_target (struct target_ops *target);

void darwin_check_osabi (darwin_inferior *inf, thread_t thread);

#endif /* __DARWIN_NAT_H__ */