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