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