Simplifly ptrace_request_to_str's implementation...
[deliverable/binutils-gdb.git] / gdb / gdbserver / lynx-low.c
1 /* Copyright (C) 2009-2013 Free Software Foundation, Inc.
2
3 This file is part of GDB.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include "server.h"
19 #include "target.h"
20 #include "lynx-low.h"
21
22 #include <limits.h>
23 #include <sys/ptrace.h>
24 #include <sys/piddef.h> /* Provides PIDGET, TIDGET, BUILDPID, etc. */
25 #include <unistd.h>
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
28 #include "gdb_wait.h"
29 #include <signal.h>
30
31 int using_threads = 1;
32
33 /* Print a debug trace on standard output if debug_threads is set. */
34
35 static void
36 lynx_debug (char *string, ...)
37 {
38 va_list args;
39
40 if (!debug_threads)
41 return;
42
43 va_start (args, string);
44 fprintf (stderr, "DEBUG(lynx): ");
45 vfprintf (stderr, string, args);
46 fprintf (stderr, "\n");
47 va_end (args);
48 }
49
50 /* Build a ptid_t given a PID and a LynxOS TID. */
51
52 static ptid_t
53 lynx_ptid_build (int pid, long tid)
54 {
55 /* brobecker/2010-06-21: It looks like the LWP field in ptids
56 should be distinct for each thread (see write_ptid where it
57 writes the thread ID from the LWP). So instead of storing
58 the LynxOS tid in the tid field of the ptid, we store it in
59 the lwp field. */
60 return ptid_build (pid, tid, 0);
61 }
62
63 /* Return the process ID of the given PTID.
64
65 This function has little reason to exist, it's just a wrapper around
66 ptid_get_pid. But since we have a getter function for the lynxos
67 ptid, it feels cleaner to have a getter for the pid as well. */
68
69 static int
70 lynx_ptid_get_pid (ptid_t ptid)
71 {
72 return ptid_get_pid (ptid);
73 }
74
75 /* Return the LynxOS tid of the given PTID. */
76
77 static long
78 lynx_ptid_get_tid (ptid_t ptid)
79 {
80 /* See lynx_ptid_build: The LynxOS tid is stored inside the lwp field
81 of the ptid. */
82 return ptid_get_lwp (ptid);
83 }
84
85 /* For a given PTID, return the associated PID as known by the LynxOS
86 ptrace layer. */
87
88 static int
89 lynx_ptrace_pid_from_ptid (ptid_t ptid)
90 {
91 return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
92 }
93
94 /* Return a string image of the ptrace REQUEST number. */
95
96 static char *
97 ptrace_request_to_str (int request)
98 {
99 #define CASE(X) case X: return #X
100 switch (request)
101 {
102 CASE(PTRACE_TRACEME);
103 CASE(PTRACE_PEEKTEXT);
104 CASE(PTRACE_PEEKDATA);
105 CASE(PTRACE_PEEKUSER);
106 CASE(PTRACE_POKETEXT);
107 CASE(PTRACE_POKEDATA);
108 CASE(PTRACE_POKEUSER);
109 CASE(PTRACE_CONT);
110 CASE(PTRACE_KILL);
111 CASE(PTRACE_SINGLESTEP);
112 CASE(PTRACE_ATTACH);
113 CASE(PTRACE_DETACH);
114 CASE(PTRACE_GETREGS);
115 CASE(PTRACE_SETREGS);
116 CASE(PTRACE_GETFPREGS);
117 CASE(PTRACE_SETFPREGS);
118 CASE(PTRACE_READDATA);
119 CASE(PTRACE_WRITEDATA);
120 CASE(PTRACE_READTEXT);
121 CASE(PTRACE_WRITETEXT);
122 CASE(PTRACE_GETFPAREGS);
123 CASE(PTRACE_SETFPAREGS);
124 CASE(PTRACE_GETWINDOW);
125 CASE(PTRACE_SETWINDOW);
126 CASE(PTRACE_SYSCALL);
127 CASE(PTRACE_DUMPCORE);
128 CASE(PTRACE_SETWRBKPT);
129 CASE(PTRACE_SETACBKPT);
130 CASE(PTRACE_CLRBKPT);
131 CASE(PTRACE_GET_UCODE);
132 #ifdef PT_READ_GPR
133 CASE(PT_READ_GPR);
134 #endif
135 #ifdef PT_WRITE_GPR
136 CASE(PT_WRITE_GPR);
137 #endif
138 #ifdef PT_READ_FPR
139 CASE(PT_READ_FPR);
140 #endif
141 #ifdef PT_WRITE_FPR
142 CASE(PT_WRITE_FPR);
143 #endif
144 #ifdef PT_READ_VPR
145 CASE(PT_READ_VPR);
146 #endif
147 #ifdef PT_WRITE_VPR
148 CASE(PT_WRITE_VPR);
149 #endif
150 #ifdef PTRACE_PEEKUSP
151 CASE(PTRACE_PEEKUSP);
152 #endif
153 #ifdef PTRACE_POKEUSP
154 CASE(PTRACE_POKEUSP);
155 #endif
156 CASE(PTRACE_PEEKTHREAD);
157 CASE(PTRACE_THREADUSER);
158 CASE(PTRACE_FPREAD);
159 CASE(PTRACE_FPWRITE);
160 CASE(PTRACE_SETSIG);
161 CASE(PTRACE_CONT_ONE);
162 CASE(PTRACE_KILL_ONE);
163 CASE(PTRACE_SINGLESTEP_ONE);
164 CASE(PTRACE_GETLOADINFO);
165 CASE(PTRACE_GETTRACESIG);
166 #ifdef PTRACE_GETTHREADLIST
167 CASE(PTRACE_GETTHREADLIST);
168 #endif
169 }
170 #undef CASE
171
172 return "<unknown-request>";
173 }
174
175 /* A wrapper around ptrace that allows us to print debug traces of
176 ptrace calls if debug traces are activated. */
177
178 static int
179 lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
180 {
181 int result;
182 const int pid = lynx_ptrace_pid_from_ptid (ptid);
183 int saved_errno;
184
185 if (debug_threads)
186 fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
187 "data=0x%x, addr2=0x%x)",
188 ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid),
189 addr, data, addr2);
190 result = ptrace (request, pid, addr, data, addr2);
191 saved_errno = errno;
192 if (debug_threads)
193 fprintf (stderr, " -> %d (=0x%x)\n", result, result);
194
195 errno = saved_errno;
196 return result;
197 }
198
199 /* Implement the create_inferior method of the target_ops vector. */
200
201 static int
202 lynx_create_inferior (char *program, char **allargs)
203 {
204 int pid;
205
206 lynx_debug ("lynx_create_inferior ()");
207
208 pid = fork ();
209 if (pid < 0)
210 perror_with_name ("fork");
211
212 if (pid == 0)
213 {
214 int pgrp;
215
216 /* Switch child to its own process group so that signals won't
217 directly affect gdbserver. */
218 pgrp = getpid();
219 setpgid (0, pgrp);
220 ioctl (0, TIOCSPGRP, &pgrp);
221 lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
222 execv (program, allargs);
223 fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
224 fflush (stderr);
225 _exit (0177);
226 }
227
228 add_process (pid, 0);
229 /* Do not add the process thread just yet, as we do not know its tid.
230 We will add it later, during the wait for the STOP event corresponding
231 to the lynx_ptrace (PTRACE_TRACEME) call above. */
232 return pid;
233 }
234
235 /* Implement the attach target_ops method. */
236
237 static int
238 lynx_attach (unsigned long pid)
239 {
240 ptid_t ptid = lynx_ptid_build (pid, 0);
241
242 if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
243 error ("Cannot attach to process %lu: %s (%d)\n", pid,
244 strerror (errno), errno);
245
246 add_process (pid, 1);
247 add_thread (ptid, NULL);
248
249 return 0;
250 }
251
252 /* Implement the resume target_ops method. */
253
254 static void
255 lynx_resume (struct thread_resume *resume_info, size_t n)
256 {
257 /* FIXME: Assume for now that n == 1. */
258 ptid_t ptid = resume_info[0].thread;
259 const int request = (resume_info[0].kind == resume_step
260 ? PTRACE_SINGLESTEP : PTRACE_CONT);
261 const int signal = resume_info[0].sig;
262
263 if (ptid_equal (ptid, minus_one_ptid))
264 ptid = thread_to_gdb_id (current_inferior);
265
266 regcache_invalidate ();
267
268 errno = 0;
269 lynx_ptrace (request, ptid, 1, signal, 0);
270 if (errno)
271 perror_with_name ("ptrace");
272 }
273
274 /* Resume the execution of the given PTID. */
275
276 static void
277 lynx_continue (ptid_t ptid)
278 {
279 struct thread_resume resume_info;
280
281 resume_info.thread = ptid;
282 resume_info.kind = resume_continue;
283 resume_info.sig = 0;
284
285 lynx_resume (&resume_info, 1);
286 }
287
288 /* Remove all inferiors and associated threads. */
289
290 static void
291 lynx_clear_inferiors (void)
292 {
293 /* We do not use private data, so nothing much to do except calling
294 clear_inferiors. */
295 clear_inferiors ();
296 }
297
298 /* A wrapper around waitpid that handles the various idiosyncrasies
299 of LynxOS' waitpid. */
300
301 static int
302 lynx_waitpid (int pid, int *stat_loc)
303 {
304 int ret = 0;
305
306 while (1)
307 {
308 ret = waitpid (pid, stat_loc, WNOHANG);
309 if (ret < 0)
310 {
311 /* An ECHILD error is not indicative of a real problem.
312 It happens for instance while waiting for the inferior
313 to stop after attaching to it. */
314 if (errno != ECHILD)
315 perror_with_name ("waitpid (WNOHANG)");
316 }
317 if (ret > 0)
318 break;
319 /* No event with WNOHANG. See if there is one with WUNTRACED. */
320 ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED);
321 if (ret < 0)
322 {
323 /* An ECHILD error is not indicative of a real problem.
324 It happens for instance while waiting for the inferior
325 to stop after attaching to it. */
326 if (errno != ECHILD)
327 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
328 }
329 if (ret > 0)
330 break;
331 usleep (1000);
332 }
333 return ret;
334 }
335
336 /* Implement the wait target_ops method. */
337
338 static ptid_t
339 lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
340 {
341 int pid;
342 int ret;
343 int wstat;
344 ptid_t new_ptid;
345
346 if (ptid_equal (ptid, minus_one_ptid))
347 pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior));
348 else
349 pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
350
351 retry:
352
353 ret = lynx_waitpid (pid, &wstat);
354 new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
355
356 /* If this is a new thread, then add it now. The reason why we do
357 this here instead of when handling new-thread events is because
358 we need to add the thread associated to the "main" thread - even
359 for non-threaded applications where the new-thread events are not
360 generated. */
361 if (!find_thread_ptid (new_ptid))
362 {
363 lynx_debug ("New thread: (pid = %d, tid = %d)",
364 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
365 add_thread (new_ptid, NULL);
366 }
367
368 if (WIFSTOPPED (wstat))
369 {
370 status->kind = TARGET_WAITKIND_STOPPED;
371 status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat));
372 lynx_debug ("process stopped with signal: %d",
373 status->value.integer);
374 }
375 else if (WIFEXITED (wstat))
376 {
377 status->kind = TARGET_WAITKIND_EXITED;
378 status->value.integer = WEXITSTATUS (wstat);
379 lynx_debug ("process exited with code: %d", status->value.integer);
380 }
381 else if (WIFSIGNALED (wstat))
382 {
383 status->kind = TARGET_WAITKIND_SIGNALLED;
384 status->value.integer = gdb_signal_from_host (WTERMSIG (wstat));
385 lynx_debug ("process terminated with code: %d",
386 status->value.integer);
387 }
388 else
389 {
390 /* Not sure what happened if we get here, or whether we can
391 in fact get here. But if we do, handle the event the best
392 we can. */
393 status->kind = TARGET_WAITKIND_STOPPED;
394 status->value.integer = gdb_signal_from_host (0);
395 lynx_debug ("unknown event ????");
396 }
397
398 /* SIGTRAP events are generated for situations other than single-step/
399 breakpoint events (Eg. new-thread events). Handle those other types
400 of events, and resume the execution if necessary. */
401 if (status->kind == TARGET_WAITKIND_STOPPED
402 && status->value.integer == GDB_SIGNAL_TRAP)
403 {
404 const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);
405
406 lynx_debug ("(realsig = %d)", realsig);
407 switch (realsig)
408 {
409 case SIGNEWTHREAD:
410 /* We just added the new thread above. No need to do anything
411 further. Just resume the execution again. */
412 lynx_continue (new_ptid);
413 goto retry;
414
415 case SIGTHREADEXIT:
416 remove_thread (find_thread_ptid (new_ptid));
417 lynx_continue (new_ptid);
418 goto retry;
419 }
420 }
421
422 return new_ptid;
423 }
424
425 /* A wrapper around lynx_wait_1 that also prints debug traces when
426 such debug traces have been activated. */
427
428 static ptid_t
429 lynx_wait (ptid_t ptid, struct target_waitstatus *status, int options)
430 {
431 ptid_t new_ptid;
432
433 lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
434 lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
435 new_ptid = lynx_wait_1 (ptid, status, options);
436 lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)",
437 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid),
438 status->kind);
439 return new_ptid;
440 }
441
442 /* Implement the kill target_ops method. */
443
444 static int
445 lynx_kill (int pid)
446 {
447 ptid_t ptid = lynx_ptid_build (pid, 0);
448 struct target_waitstatus status;
449 struct process_info *process;
450
451 process = find_process_pid (pid);
452 if (process == NULL)
453 return -1;
454
455 lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0);
456 lynx_wait (ptid, &status, 0);
457 the_target->mourn (process);
458 return 0;
459 }
460
461 /* Implement the detach target_ops method. */
462
463 static int
464 lynx_detach (int pid)
465 {
466 ptid_t ptid = lynx_ptid_build (pid, 0);
467 struct process_info *process;
468
469 process = find_process_pid (pid);
470 if (process == NULL)
471 return -1;
472
473 lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0);
474 the_target->mourn (process);
475 return 0;
476 }
477
478 /* Implement the mourn target_ops method. */
479
480 static void
481 lynx_mourn (struct process_info *proc)
482 {
483 lynx_clear_inferiors ();
484 }
485
486 /* Implement the join target_ops method. */
487
488 static void
489 lynx_join (int pid)
490 {
491 /* The PTRACE_DETACH is sufficient to detach from the process.
492 So no need to do anything extra. */
493 }
494
495 /* Implement the thread_alive target_ops method. */
496
497 static int
498 lynx_thread_alive (ptid_t ptid)
499 {
500 /* The list of threads is updated at the end of each wait, so it
501 should be up to date. No need to re-fetch it. */
502 return (find_thread_ptid (ptid) != NULL);
503 }
504
505 /* Implement the fetch_registers target_ops method. */
506
507 static void
508 lynx_fetch_registers (struct regcache *regcache, int regno)
509 {
510 struct lynx_regset_info *regset = lynx_target_regsets;
511 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
512
513 lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
514
515 while (regset->size >= 0)
516 {
517 char *buf;
518 int res;
519
520 buf = xmalloc (regset->size);
521 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
522 if (res < 0)
523 perror ("ptrace");
524 regset->store_function (regcache, buf);
525 free (buf);
526 regset++;
527 }
528 }
529
530 /* Implement the store_registers target_ops method. */
531
532 static void
533 lynx_store_registers (struct regcache *regcache, int regno)
534 {
535 struct lynx_regset_info *regset = lynx_target_regsets;
536 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
537
538 lynx_debug ("lynx_store_registers (regno = %d)", regno);
539
540 while (regset->size >= 0)
541 {
542 char *buf;
543 int res;
544
545 buf = xmalloc (regset->size);
546 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
547 if (res == 0)
548 {
549 /* Then overlay our cached registers on that. */
550 regset->fill_function (regcache, buf);
551 /* Only now do we write the register set. */
552 res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf,
553 0, 0);
554 }
555 if (res < 0)
556 perror ("ptrace");
557 free (buf);
558 regset++;
559 }
560 }
561
562 /* Implement the read_memory target_ops method. */
563
564 static int
565 lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
566 {
567 /* On LynxOS, memory reads needs to be performed in chunks the size
568 of int types, and they should also be aligned accordingly. */
569 int buf;
570 const int xfer_size = sizeof (buf);
571 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
572 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
573
574 while (addr < memaddr + len)
575 {
576 int skip = 0;
577 int truncate = 0;
578
579 errno = 0;
580 if (addr < memaddr)
581 skip = memaddr - addr;
582 if (addr + xfer_size > memaddr + len)
583 truncate = addr + xfer_size - memaddr - len;
584 buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
585 if (errno)
586 return errno;
587 memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip,
588 xfer_size - skip - truncate);
589 addr += xfer_size;
590 }
591
592 return 0;
593 }
594
595 /* Implement the write_memory target_ops method. */
596
597 static int
598 lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
599 {
600 /* On LynxOS, memory writes needs to be performed in chunks the size
601 of int types, and they should also be aligned accordingly. */
602 int buf;
603 const int xfer_size = sizeof (buf);
604 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
605 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
606
607 while (addr < memaddr + len)
608 {
609 int skip = 0;
610 int truncate = 0;
611
612 if (addr < memaddr)
613 skip = memaddr - addr;
614 if (addr + xfer_size > memaddr + len)
615 truncate = addr + xfer_size - memaddr - len;
616 if (skip > 0 || truncate > 0)
617 /* We need to read the memory at this address in order to preserve
618 the data that we are not overwriting. */
619 lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
620 if (errno)
621 return errno;
622 memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
623 xfer_size - skip - truncate);
624 errno = 0;
625 lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
626 if (errno)
627 return errno;
628 addr += xfer_size;
629 }
630
631 return 0;
632 }
633
634 /* Implement the kill_request target_ops method. */
635
636 static void
637 lynx_request_interrupt (void)
638 {
639 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
640
641 kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
642 }
643
644 /* The LynxOS target_ops vector. */
645
646 static struct target_ops lynx_target_ops = {
647 lynx_create_inferior,
648 lynx_attach,
649 lynx_kill,
650 lynx_detach,
651 lynx_mourn,
652 lynx_join,
653 lynx_thread_alive,
654 lynx_resume,
655 lynx_wait,
656 lynx_fetch_registers,
657 lynx_store_registers,
658 NULL, /* prepare_to_access_memory */
659 NULL, /* done_accessing_memory */
660 lynx_read_memory,
661 lynx_write_memory,
662 NULL, /* look_up_symbols */
663 lynx_request_interrupt,
664 NULL, /* read_auxv */
665 NULL, /* insert_point */
666 NULL, /* remove_point */
667 NULL, /* stopped_by_watchpoint */
668 NULL, /* stopped_data_address */
669 NULL, /* read_offsets */
670 NULL, /* get_tls_address */
671 NULL, /* qxfer_spu */
672 NULL, /* hostio_last_error */
673 NULL, /* qxfer_osdata */
674 NULL, /* qxfer_siginfo */
675 NULL, /* supports_non_stop */
676 NULL, /* async */
677 NULL, /* start_non_stop */
678 NULL, /* supports_multi_process */
679 NULL, /* handle_monitor_command */
680 };
681
682 void
683 initialize_low (void)
684 {
685 set_target_ops (&lynx_target_ops);
686 the_low_target.arch_setup ();
687 }
688
This page took 0.050976 seconds and 5 git commands to generate.