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