Share fork_inferior et al with gdbserver
[deliverable/binutils-gdb.git] / gdb / gdbserver / target.c
CommitLineData
ce3a066d 1/* Target operations for the remote server for GDB.
61baf725 2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
ce3a066d
DJ
3
4 Contributed by MontaVista Software.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
a9762ec7 10 the Free Software Foundation; either version 3 of the License, or
ce3a066d
DJ
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
a9762ec7 19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
ce3a066d
DJ
20
21#include "server.h"
c144c7a0 22#include "tracepoint.h"
ce3a066d
DJ
23
24struct target_ops *the_target;
25
f0db101d 26int
0bfdf32f 27set_desired_thread (int use_general)
0d62e5e8
DJ
28{
29 struct thread_info *found;
30
31 if (use_general == 1)
e09875d4 32 found = find_thread_ptid (general_thread);
0d62e5e8 33 else
943ca1dd 34 found = find_thread_ptid (cont_thread);
0d62e5e8 35
f0db101d
PA
36 current_thread = found;
37 return (current_thread != NULL);
0d62e5e8
DJ
38}
39
a67a9fae
PA
40/* Structure used to look up a thread to use as current when accessing
41 memory. */
42
43struct thread_search
44{
45 /* The PTID of the current general thread. This is an input
46 parameter. */
47 ptid_t current_gen_ptid;
48
49 /* The first thread found. */
50 struct thread_info *first;
51
52 /* The first stopped thread found. */
53 struct thread_info *stopped;
54
55 /* The current general thread, if found. */
56 struct thread_info *current;
57};
58
59/* Callback for find_inferior. Search for a thread to use as current
60 when accessing memory. */
61
62static int
63thread_search_callback (struct inferior_list_entry *entry, void *args)
64{
65 struct thread_info *thread = (struct thread_info *) entry;
66 struct thread_search *s = (struct thread_search *) args;
67
68 if (ptid_get_pid (entry->id) == ptid_get_pid (s->current_gen_ptid)
69 && mythread_alive (ptid_of (thread)))
70 {
0e50fe5c
JB
71 if (s->stopped == NULL
72 && the_target->thread_stopped != NULL
73 && thread_stopped (thread))
a67a9fae
PA
74 s->stopped = thread;
75
76 if (s->first == NULL)
77 s->first = thread;
78
79 if (s->current == NULL && ptid_equal (s->current_gen_ptid, entry->id))
80 s->current = thread;
81 }
82
83 return 0;
84}
85
86/* The thread that was current before prepare_to_access_memory was
87 called. done_accessing_memory uses this to restore the previous
88 selected thread. */
89static ptid_t prev_general_thread;
90
91/* See target.h. */
92
93int
94prepare_to_access_memory (void)
95{
96 struct thread_search search;
97 struct thread_info *thread;
98
99 memset (&search, 0, sizeof (search));
100 search.current_gen_ptid = general_thread;
101 prev_general_thread = general_thread;
102
103 if (the_target->prepare_to_access_memory != NULL)
104 {
105 int res;
106
107 res = the_target->prepare_to_access_memory ();
108 if (res != 0)
109 return res;
110 }
111
112 find_inferior (&all_threads, thread_search_callback, &search);
113
114 /* Prefer a stopped thread. If none is found, try the current
115 thread. Otherwise, take the first thread in the process. If
116 none is found, undo the effects of
117 target->prepare_to_access_memory() and return error. */
118 if (search.stopped != NULL)
119 thread = search.stopped;
120 else if (search.current != NULL)
121 thread = search.current;
122 else if (search.first != NULL)
123 thread = search.first;
124 else
125 {
126 done_accessing_memory ();
127 return 1;
128 }
129
130 current_thread = thread;
131 general_thread = ptid_of (thread);
132
133 return 0;
134}
135
136/* See target.h. */
137
138void
139done_accessing_memory (void)
140{
141 if (the_target->done_accessing_memory != NULL)
142 the_target->done_accessing_memory ();
143
144 /* Restore the previous selected thread. */
145 general_thread = prev_general_thread;
146 current_thread = find_thread_ptid (general_thread);
147}
148
c3e735a6 149int
f450004a 150read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
611cb4a5 151{
c3e735a6
DJ
152 int res;
153 res = (*the_target->read_memory) (memaddr, myaddr, len);
611cb4a5 154 check_mem_read (memaddr, myaddr, len);
c3e735a6 155 return res;
611cb4a5
DJ
156}
157
721ec300
GB
158/* See target/target.h. */
159
160int
161target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
162{
163 return read_inferior_memory (memaddr, myaddr, len);
164}
165
166/* See target/target.h. */
167
168int
169target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
170{
171 return read_inferior_memory (memaddr, (gdb_byte *) result, sizeof (*result));
172}
173
611cb4a5 174int
f450004a
DJ
175write_inferior_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
176 int len)
0d62e5e8
DJ
177{
178 /* Lacking cleanups, there is some potential for a memory leak if the
179 write fails and we go through error(). Make sure that no more than
180 one buffer is ever pending by making BUFFER static. */
f450004a 181 static unsigned char *buffer = 0;
0d62e5e8
DJ
182 int res;
183
184 if (buffer != NULL)
185 free (buffer);
186
224c3ddb 187 buffer = (unsigned char *) xmalloc (len);
0d62e5e8 188 memcpy (buffer, myaddr, len);
b9fd1791 189 check_mem_write (memaddr, buffer, myaddr, len);
0d62e5e8
DJ
190 res = (*the_target->write_memory) (memaddr, buffer, len);
191 free (buffer);
192 buffer = NULL;
193
194 return res;
195}
196
721ec300
GB
197/* See target/target.h. */
198
199int
200target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
201{
202 return write_inferior_memory (memaddr, myaddr, len);
203}
204
95954743
PA
205ptid_t
206mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
bd99dc85 207 int connected_wait)
611cb4a5 208{
95954743 209 ptid_t ret;
0d62e5e8
DJ
210
211 if (connected_wait)
212 server_waiting = 1;
213
f2b9e3df 214 ret = target_wait (ptid, ourstatus, options);
bd99dc85 215
4210d83e
PA
216 /* We don't expose _LOADED events to gdbserver core. See the
217 `dlls_changed' global. */
218 if (ourstatus->kind == TARGET_WAITKIND_LOADED)
219 ourstatus->kind = TARGET_WAITKIND_STOPPED;
220
1a3d890b
PA
221 /* If GDB is connected through TCP/serial, then GDBserver will most
222 probably be running on its own terminal/console, so it's nice to
223 print there why is GDBserver exiting. If however, GDB is
224 connected through stdio, then there's no need to spam the GDB
225 console with this -- the user will already see the exit through
226 regular GDB output, in that same terminal. */
227 if (!remote_connection_is_stdio ())
228 {
229 if (ourstatus->kind == TARGET_WAITKIND_EXITED)
230 fprintf (stderr,
231 "\nChild exited with status %d\n", ourstatus->value.integer);
232 else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
233 fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
234 gdb_signal_to_host (ourstatus->value.sig),
235 gdb_signal_to_name (ourstatus->value.sig));
236 }
0d62e5e8
DJ
237
238 if (connected_wait)
239 server_waiting = 0;
240
241 return ret;
611cb4a5
DJ
242}
243
f8c1d06b
GB
244/* See target/target.h. */
245
246void
03f4463b 247target_stop_and_wait (ptid_t ptid)
f8c1d06b
GB
248{
249 struct target_waitstatus status;
250 int was_non_stop = non_stop;
17e16485 251 struct thread_resume resume_info;
f8c1d06b 252
17e16485
YQ
253 resume_info.thread = ptid;
254 resume_info.kind = resume_stop;
255 resume_info.sig = GDB_SIGNAL_0;
256 (*the_target->resume) (&resume_info, 1);
f8c1d06b
GB
257
258 non_stop = 1;
259 mywait (ptid, &status, 0, 0);
260 non_stop = was_non_stop;
261}
262
263/* See target/target.h. */
264
f2b9e3df
SDJ
265ptid_t
266target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
267{
268 return (*the_target->wait) (ptid, status, options);
269}
270
271/* See target/target.h. */
272
bc1e6c81
SDJ
273void
274target_mourn_inferior (ptid_t ptid)
275{
276 (*the_target->mourn) (find_process_pid (ptid_get_pid (ptid)));
277}
278
279/* See target/target.h. */
280
f8c1d06b 281void
03f4463b 282target_continue_no_signal (ptid_t ptid)
f8c1d06b
GB
283{
284 struct thread_resume resume_info;
285
286 resume_info.thread = ptid;
287 resume_info.kind = resume_continue;
288 resume_info.sig = GDB_SIGNAL_0;
289 (*the_target->resume) (&resume_info, 1);
290}
291
049a8570
SDJ
292/* See target/target.h. */
293
294void
295target_continue (ptid_t ptid, enum gdb_signal signal)
296{
297 struct thread_resume resume_info;
298
299 resume_info.thread = ptid;
300 resume_info.kind = resume_continue;
301 resume_info.sig = gdb_signal_to_host (signal);
302 (*the_target->resume) (&resume_info, 1);
303}
304
1fb77080
SDJ
305/* See target/target.h. */
306
307int
308target_supports_multi_process (void)
309{
310 return (the_target->supports_multi_process != NULL ?
311 (*the_target->supports_multi_process) () : 0);
312}
313
bd99dc85
PA
314int
315start_non_stop (int nonstop)
316{
317 if (the_target->start_non_stop == NULL)
318 {
319 if (nonstop)
320 return -1;
321 else
322 return 0;
323 }
324
325 return (*the_target->start_non_stop) (nonstop);
326}
327
ce3a066d
DJ
328void
329set_target_ops (struct target_ops *target)
330{
8d749320 331 the_target = XNEW (struct target_ops);
ce3a066d
DJ
332 memcpy (the_target, target, sizeof (*the_target));
333}
95954743
PA
334
335/* Convert pid to printable format. */
336
337const char *
338target_pid_to_str (ptid_t ptid)
339{
340 static char buf[80];
341
342 if (ptid_equal (ptid, minus_one_ptid))
6cebaf6e 343 xsnprintf (buf, sizeof (buf), "<all threads>");
95954743 344 else if (ptid_equal (ptid, null_ptid))
6cebaf6e 345 xsnprintf (buf, sizeof (buf), "<null thread>");
95954743 346 else if (ptid_get_tid (ptid) != 0)
6cebaf6e 347 xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx",
348 ptid_get_pid (ptid), ptid_get_tid (ptid));
95954743 349 else if (ptid_get_lwp (ptid) != 0)
6cebaf6e 350 xsnprintf (buf, sizeof (buf), "LWP %d.%ld",
351 ptid_get_pid (ptid), ptid_get_lwp (ptid));
95954743 352 else
6cebaf6e 353 xsnprintf (buf, sizeof (buf), "Process %d",
354 ptid_get_pid (ptid));
95954743
PA
355
356 return buf;
357}
8336d594 358
7255706c
YQ
359int
360kill_inferior (int pid)
361{
362 gdb_agent_about_to_close (pid);
363
364 return (*the_target->kill) (pid);
365}
70b90b91
YQ
366
367/* Target can do hardware single step. */
368
369int
370target_can_do_hardware_single_step (void)
371{
372 return 1;
373}
2e6ee069
AT
374
375/* Default implementation for breakpoint_kind_for_pc.
376
377 The default behavior for targets that don't implement breakpoint_kind_for_pc
378 is to use the size of a breakpoint as the kind. */
379
380int
381default_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
382{
383 int size = 0;
384
385 gdb_assert (the_target->sw_breakpoint_from_kind != NULL);
386
387 (*the_target->sw_breakpoint_from_kind) (0, &size);
388 return size;
389}
2090129c
SDJ
390
391/* See target/target.h. */
392
393void
394target_terminal_init ()
395{
396 /* Placeholder needed because of fork_inferior. Not necessary on
397 GDBserver. */
398}
399
400/* See target/target.h. */
401
402void
403target_terminal_inferior ()
404{
405 /* Placeholder needed because of fork_inferior. Not necessary on
406 GDBserver. */
407}
408
409/* See target/target.h. */
410
411void
412target_terminal_ours ()
413{
414 /* Placeholder needed because of fork_inferior. Not necessary on
415 GDBserver. */
416}
This page took 1.117813 seconds and 4 git commands to generate.