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