xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/darwin-nat.h (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
1 /* Common things used by the various darwin files
2    Copyright (C) 1995-2023 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
16 
17 #ifndef DARWIN_NAT_H
18 #define DARWIN_NAT_H
19 
20 #include "inf-child.h"
21 #include <mach/mach.h>
22 #include "gdbthread.h"
23 
24 struct darwin_exception_msg
25 {
26   mach_msg_header_t header;
27 
28   /* Thread and task taking the exception.  */
29   mach_port_t thread_port;
30   mach_port_t task_port;
31 
32   /* Type of the exception.  */
33   exception_type_t ex_type;
34 
35   /* Machine dependent details.  */
36   mach_msg_type_number_t data_count;
37   integer_t ex_data[2];
38 };
39 
40 enum darwin_msg_state
41 {
42   /* The thread is running.  */
43   DARWIN_RUNNING,
44 
45   /* The thread is stopped.  */
46   DARWIN_STOPPED,
47 
48   /* The thread has sent a message and waits for a reply.  */
49   DARWIN_MESSAGE
50 };
51 
52 struct darwin_thread_info : public private_thread_info
53 {
54   /* The thread port from a GDB point of view.  */
55   thread_t gdb_port = 0;
56 
57   /* The thread port from the inferior point of view.  Not to be used inside
58      gdb except for get_ada_task_ptid.  */
59   thread_t inf_port = 0;
60 
61   /* Current message state.
62      If the kernel has sent a message it expects a reply and the inferior
63      can't be killed before.  */
64   enum darwin_msg_state msg_state = DARWIN_RUNNING;
65 
66   /* True if this thread is single-stepped.  */
67   bool single_step = false;
68 
69   /* True if a signal was manually sent to the thread.  */
70   bool signaled = false;
71 
72   /* The last exception received.  */
73   struct darwin_exception_msg event {};
74 };
75 typedef struct darwin_thread_info darwin_thread_t;
76 
77 /* This needs to be overridden by the platform specific nat code.  */
78 
79 class darwin_nat_target : public inf_child_target
80 {
81   void create_inferior (const char *exec_file,
82 			const std::string &allargs,
83 			char **env, int from_tty) override;
84 
85   void attach (const char *, int) override;
86 
87   void detach (inferior *, int) override;
88 
89   ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
90 
91   void mourn_inferior () override;
92 
93   void kill () override;
94 
95   void interrupt () override;
96 
97   void resume (ptid_t, int , enum gdb_signal) override;
98 
99   bool thread_alive (ptid_t ptid) override;
100 
101   std::string pid_to_str (ptid_t) override;
102 
103   const char *pid_to_exec_file (int pid) override;
104 
105   enum target_xfer_status xfer_partial (enum target_object object,
106 					const char *annex,
107 					gdb_byte *readbuf,
108 					const gdb_byte *writebuf,
109 					ULONGEST offset, ULONGEST len,
110 					ULONGEST *xfered_len) override;
111 
112   bool supports_multi_process () override;
113 
114   ptid_t get_ada_task_ptid (long lwp, ULONGEST thread) override;
115 
116 private:
117   ptid_t wait_1 (ptid_t, struct target_waitstatus *);
118   void check_new_threads (inferior *inf);
119   int decode_exception_message (mach_msg_header_t *hdr,
120 				inferior **pinf,
121 				darwin_thread_t **pthread);
122   ptid_t decode_message (mach_msg_header_t *hdr,
123 			 darwin_thread_t **pthread,
124 			 inferior **pinf,
125 			 target_waitstatus *status);
126   void stop_inferior (inferior *inf);
127   void init_thread_list (inferior *inf);
128   void ptrace_him (int pid);
129   int cancel_breakpoint (ptid_t ptid);
130 };
131 
132 /* Describe the mach exception handling state for a task.  This state is saved
133    before being changed and restored when a process is detached.
134    For more information on these fields see task_get_exception_ports manual
135    page.  */
136 struct darwin_exception_info
137 {
138   /* Exceptions handled by the port.  */
139   exception_mask_t masks[EXC_TYPES_COUNT] {};
140 
141   /* Ports receiving exception messages.  */
142   mach_port_t ports[EXC_TYPES_COUNT] {};
143 
144   /* Type of messages sent.  */
145   exception_behavior_t behaviors[EXC_TYPES_COUNT] {};
146 
147   /* Type of state to be sent.  */
148   thread_state_flavor_t flavors[EXC_TYPES_COUNT] {};
149 
150   /* Number of elements set.  */
151   mach_msg_type_number_t count = 0;
152 };
153 
154 static inline darwin_thread_info *
155 get_darwin_thread_info (class thread_info *thread)
156 {
157   return gdb::checked_static_cast<darwin_thread_info *> (thread->priv.get ());
158 }
159 
160 /* Describe an inferior.  */
161 struct darwin_inferior : public private_inferior
162 {
163   /* Corresponding task port.  */
164   task_t task = 0;
165 
166   /* Port which will receive the dead-name notification for the task port.
167      This is used to detect the death of the task.  */
168   mach_port_t notify_port = 0;
169 
170   /* Initial exception handling.  */
171   darwin_exception_info exception_info;
172 
173   /* Number of messages that have been received but not yet replied.  */
174   unsigned int pending_messages = 0;
175 
176   /* Set if inferior is not controlled by ptrace(2) but through Mach.  */
177   bool no_ptrace = false;
178 
179   /* True if this task is suspended.  */
180   bool suspended = false;
181 
182   /* Sorted vector of known threads.  */
183   std::vector<darwin_thread_t *> threads;
184 };
185 
186 /* Return the darwin_inferior attached to INF.  */
187 
188 static inline darwin_inferior *
189 get_darwin_inferior (inferior *inf)
190 {
191   return gdb::checked_static_cast<darwin_inferior *> (inf->priv.get ());
192 }
193 
194 /* Exception port.  */
195 extern mach_port_t darwin_ex_port;
196 
197 /* Port set.  */
198 extern mach_port_t darwin_port_set;
199 
200 /* A copy of mach_host_self ().  */
201 extern mach_port_t darwin_host_self;
202 
203 #define MACH_CHECK_ERROR(ret) \
204   mach_check_error (ret, __FILE__, __LINE__, __func__)
205 
206 extern void mach_check_error (kern_return_t ret, const char *file,
207 			      unsigned int line, const char *func);
208 
209 void darwin_set_sstep (thread_t thread, int enable);
210 
211 void darwin_check_osabi (darwin_inferior *inf, thread_t thread);
212 
213 #endif /* DARWIN_NAT_H */
214