Replace write_inferior_memory with target_write_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
4196ab2a
TT
149/* See target/target.h. */
150
611cb4a5 151int
4196ab2a
TT
152target_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr,
153 ssize_t len)
0d62e5e8 154{
c6778d00
TT
155 /* Make a copy of the data because check_mem_write may need to
156 update it. */
157 std::vector<unsigned char> buffer (myaddr, myaddr + len);
158 check_mem_write (memaddr, buffer.data (), myaddr, len);
159 return (*the_target->write_memory) (memaddr, buffer.data (), len);
0d62e5e8
DJ
160}
161
95954743
PA
162ptid_t
163mywait (ptid_t ptid, struct target_waitstatus *ourstatus, int options,
bd99dc85 164 int connected_wait)
611cb4a5 165{
95954743 166 ptid_t ret;
0d62e5e8
DJ
167
168 if (connected_wait)
169 server_waiting = 1;
170
f2b9e3df 171 ret = target_wait (ptid, ourstatus, options);
bd99dc85 172
4210d83e
PA
173 /* We don't expose _LOADED events to gdbserver core. See the
174 `dlls_changed' global. */
175 if (ourstatus->kind == TARGET_WAITKIND_LOADED)
176 ourstatus->kind = TARGET_WAITKIND_STOPPED;
177
1a3d890b
PA
178 /* If GDB is connected through TCP/serial, then GDBserver will most
179 probably be running on its own terminal/console, so it's nice to
180 print there why is GDBserver exiting. If however, GDB is
181 connected through stdio, then there's no need to spam the GDB
182 console with this -- the user will already see the exit through
183 regular GDB output, in that same terminal. */
184 if (!remote_connection_is_stdio ())
185 {
186 if (ourstatus->kind == TARGET_WAITKIND_EXITED)
187 fprintf (stderr,
188 "\nChild exited with status %d\n", ourstatus->value.integer);
189 else if (ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
190 fprintf (stderr, "\nChild terminated with signal = 0x%x (%s)\n",
191 gdb_signal_to_host (ourstatus->value.sig),
192 gdb_signal_to_name (ourstatus->value.sig));
193 }
0d62e5e8
DJ
194
195 if (connected_wait)
196 server_waiting = 0;
197
198 return ret;
611cb4a5
DJ
199}
200
f8c1d06b
GB
201/* See target/target.h. */
202
203void
03f4463b 204target_stop_and_wait (ptid_t ptid)
f8c1d06b
GB
205{
206 struct target_waitstatus status;
207 int was_non_stop = non_stop;
17e16485 208 struct thread_resume resume_info;
f8c1d06b 209
17e16485
YQ
210 resume_info.thread = ptid;
211 resume_info.kind = resume_stop;
212 resume_info.sig = GDB_SIGNAL_0;
213 (*the_target->resume) (&resume_info, 1);
f8c1d06b
GB
214
215 non_stop = 1;
216 mywait (ptid, &status, 0, 0);
217 non_stop = was_non_stop;
218}
219
220/* See target/target.h. */
221
f2b9e3df
SDJ
222ptid_t
223target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
224{
225 return (*the_target->wait) (ptid, status, options);
226}
227
228/* See target/target.h. */
229
bc1e6c81
SDJ
230void
231target_mourn_inferior (ptid_t ptid)
232{
e99b03dc 233 (*the_target->mourn) (find_process_pid (ptid.pid ()));
bc1e6c81
SDJ
234}
235
236/* See target/target.h. */
237
f8c1d06b 238void
03f4463b 239target_continue_no_signal (ptid_t ptid)
f8c1d06b
GB
240{
241 struct thread_resume resume_info;
242
243 resume_info.thread = ptid;
244 resume_info.kind = resume_continue;
245 resume_info.sig = GDB_SIGNAL_0;
246 (*the_target->resume) (&resume_info, 1);
247}
248
049a8570
SDJ
249/* See target/target.h. */
250
251void
252target_continue (ptid_t ptid, enum gdb_signal signal)
253{
254 struct thread_resume resume_info;
255
256 resume_info.thread = ptid;
257 resume_info.kind = resume_continue;
258 resume_info.sig = gdb_signal_to_host (signal);
259 (*the_target->resume) (&resume_info, 1);
260}
261
1fb77080
SDJ
262/* See target/target.h. */
263
264int
265target_supports_multi_process (void)
266{
267 return (the_target->supports_multi_process != NULL ?
268 (*the_target->supports_multi_process) () : 0);
269}
270
bd99dc85
PA
271int
272start_non_stop (int nonstop)
273{
274 if (the_target->start_non_stop == NULL)
275 {
276 if (nonstop)
277 return -1;
278 else
279 return 0;
280 }
281
282 return (*the_target->start_non_stop) (nonstop);
283}
284
ce3a066d
DJ
285void
286set_target_ops (struct target_ops *target)
287{
8d749320 288 the_target = XNEW (struct target_ops);
ce3a066d
DJ
289 memcpy (the_target, target, sizeof (*the_target));
290}
95954743
PA
291
292/* Convert pid to printable format. */
293
294const char *
295target_pid_to_str (ptid_t ptid)
296{
297 static char buf[80];
298
d7e15655 299 if (ptid == minus_one_ptid)
6cebaf6e 300 xsnprintf (buf, sizeof (buf), "<all threads>");
d7e15655 301 else if (ptid == null_ptid)
6cebaf6e 302 xsnprintf (buf, sizeof (buf), "<null thread>");
cc6bcb54 303 else if (ptid.tid () != 0)
6cebaf6e 304 xsnprintf (buf, sizeof (buf), "Thread %d.0x%lx",
cc6bcb54 305 ptid.pid (), ptid.tid ());
e38504b3 306 else if (ptid.lwp () != 0)
6cebaf6e 307 xsnprintf (buf, sizeof (buf), "LWP %d.%ld",
e38504b3 308 ptid.pid (), ptid.lwp ());
95954743 309 else
6cebaf6e 310 xsnprintf (buf, sizeof (buf), "Process %d",
e99b03dc 311 ptid.pid ());
95954743
PA
312
313 return buf;
314}
8336d594 315
7255706c 316int
a780ef4f 317kill_inferior (process_info *proc)
7255706c 318{
a780ef4f 319 gdb_agent_about_to_close (proc->pid);
7255706c 320
a780ef4f 321 return (*the_target->kill) (proc);
7255706c 322}
70b90b91
YQ
323
324/* Target can do hardware single step. */
325
326int
327target_can_do_hardware_single_step (void)
328{
329 return 1;
330}
2e6ee069
AT
331
332/* Default implementation for breakpoint_kind_for_pc.
333
334 The default behavior for targets that don't implement breakpoint_kind_for_pc
335 is to use the size of a breakpoint as the kind. */
336
337int
338default_breakpoint_kind_from_pc (CORE_ADDR *pcptr)
339{
340 int size = 0;
341
342 gdb_assert (the_target->sw_breakpoint_from_kind != NULL);
343
344 (*the_target->sw_breakpoint_from_kind) (0, &size);
345 return size;
346}
2090129c 347
223ffa71
TT
348/* Define it. */
349
e671cd59
PA
350target_terminal_state target_terminal::m_terminal_state
351 = target_terminal_state::is_ours;
223ffa71 352
2090129c
SDJ
353/* See target/target.h. */
354
355void
223ffa71 356target_terminal::init ()
2090129c
SDJ
357{
358 /* Placeholder needed because of fork_inferior. Not necessary on
359 GDBserver. */
360}
361
362/* See target/target.h. */
363
364void
223ffa71 365target_terminal::inferior ()
2090129c
SDJ
366{
367 /* Placeholder needed because of fork_inferior. Not necessary on
368 GDBserver. */
369}
370
371/* See target/target.h. */
372
373void
223ffa71 374target_terminal::ours ()
2090129c
SDJ
375{
376 /* Placeholder needed because of fork_inferior. Not necessary on
377 GDBserver. */
378}
223ffa71
TT
379
380/* See target/target.h. */
381
382void
383target_terminal::ours_for_output (void)
384{
385 /* Placeholder. */
386}
387
388/* See target/target.h. */
389
390void
391target_terminal::info (const char *arg, int from_tty)
392{
393 /* Placeholder. */
394}
This page took 1.323527 seconds and 4 git commands to generate.