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
lynx_debug(char * string,...)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
lynx_ptid_build(int pid,long tid)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
lynx_ptid_get_pid(ptid_t ptid)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
lynx_ptid_get_tid(ptid_t ptid)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
lynx_ptrace_pid_from_ptid(ptid_t ptid)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 *
ptrace_request_to_str(int request)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
lynx_ptrace(int request,ptid_t ptid,int addr,int data,int addr2)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
lynx_create_inferior(char * program,char ** allargs)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 if (!remote_connection_is_stdio ())
222 {
223 close (listen_desc);
224 if (gdb_connected ())
225 close (remote_desc);
226 }
227 lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
228 execv (program, allargs);
229 fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
230 fflush (stderr);
231 _exit (0177);
232 }
233
234 add_process (pid, 0);
235 /* Do not add the process thread just yet, as we do not know its tid.
236 We will add it later, during the wait for the STOP event corresponding
237 to the lynx_ptrace (PTRACE_TRACEME) call above. */
238 return pid;
239 }
240
241 /* Implement the attach target_ops method. */
242
243 static int
lynx_attach(unsigned long pid)244 lynx_attach (unsigned long pid)
245 {
246 ptid_t ptid = lynx_ptid_build (pid, 0);
247
248 if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
249 error ("Cannot attach to process %lu: %s (%d)\n", pid,
250 strerror (errno), errno);
251
252 add_process (pid, 1);
253 add_thread (ptid, NULL);
254
255 return 0;
256 }
257
258 /* Implement the resume target_ops method. */
259
260 static void
lynx_resume(struct thread_resume * resume_info,size_t n)261 lynx_resume (struct thread_resume *resume_info, size_t n)
262 {
263 /* FIXME: Assume for now that n == 1. */
264 ptid_t ptid = resume_info[0].thread;
265 const int request = (resume_info[0].kind == resume_step
266 ? PTRACE_SINGLESTEP : PTRACE_CONT);
267 const int signal = resume_info[0].sig;
268
269 if (ptid_equal (ptid, minus_one_ptid))
270 ptid = thread_to_gdb_id (current_inferior);
271
272 regcache_invalidate ();
273
274 errno = 0;
275 lynx_ptrace (request, ptid, 1, signal, 0);
276 if (errno)
277 perror_with_name ("ptrace");
278 }
279
280 /* Resume the execution of the given PTID. */
281
282 static void
lynx_continue(ptid_t ptid)283 lynx_continue (ptid_t ptid)
284 {
285 struct thread_resume resume_info;
286
287 resume_info.thread = ptid;
288 resume_info.kind = resume_continue;
289 resume_info.sig = 0;
290
291 lynx_resume (&resume_info, 1);
292 }
293
294 /* Remove all inferiors and associated threads. */
295
296 static void
lynx_clear_inferiors(void)297 lynx_clear_inferiors (void)
298 {
299 /* We do not use private data, so nothing much to do except calling
300 clear_inferiors. */
301 clear_inferiors ();
302 }
303
304 /* A wrapper around waitpid that handles the various idiosyncrasies
305 of LynxOS' waitpid. */
306
307 static int
lynx_waitpid(int pid,int * stat_loc)308 lynx_waitpid (int pid, int *stat_loc)
309 {
310 int ret = 0;
311
312 while (1)
313 {
314 ret = waitpid (pid, stat_loc, WNOHANG);
315 if (ret < 0)
316 {
317 /* An ECHILD error is not indicative of a real problem.
318 It happens for instance while waiting for the inferior
319 to stop after attaching to it. */
320 if (errno != ECHILD)
321 perror_with_name ("waitpid (WNOHANG)");
322 }
323 if (ret > 0)
324 break;
325 /* No event with WNOHANG. See if there is one with WUNTRACED. */
326 ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED);
327 if (ret < 0)
328 {
329 /* An ECHILD error is not indicative of a real problem.
330 It happens for instance while waiting for the inferior
331 to stop after attaching to it. */
332 if (errno != ECHILD)
333 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
334 }
335 if (ret > 0)
336 break;
337 usleep (1000);
338 }
339 return ret;
340 }
341
342 /* Implement the wait target_ops method. */
343
344 static ptid_t
lynx_wait_1(ptid_t ptid,struct target_waitstatus * status,int options)345 lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
346 {
347 int pid;
348 int ret;
349 int wstat;
350 ptid_t new_ptid;
351
352 if (ptid_equal (ptid, minus_one_ptid))
353 pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior));
354 else
355 pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
356
357 retry:
358
359 ret = lynx_waitpid (pid, &wstat);
360 new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
361
362 /* If this is a new thread, then add it now. The reason why we do
363 this here instead of when handling new-thread events is because
364 we need to add the thread associated to the "main" thread - even
365 for non-threaded applications where the new-thread events are not
366 generated. */
367 if (!find_thread_ptid (new_ptid))
368 {
369 lynx_debug ("New thread: (pid = %d, tid = %d)",
370 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
371 add_thread (new_ptid, NULL);
372 }
373
374 if (WIFSTOPPED (wstat))
375 {
376 status->kind = TARGET_WAITKIND_STOPPED;
377 status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat));
378 lynx_debug ("process stopped with signal: %d",
379 status->value.integer);
380 }
381 else if (WIFEXITED (wstat))
382 {
383 status->kind = TARGET_WAITKIND_EXITED;
384 status->value.integer = WEXITSTATUS (wstat);
385 lynx_debug ("process exited with code: %d", status->value.integer);
386 }
387 else if (WIFSIGNALED (wstat))
388 {
389 status->kind = TARGET_WAITKIND_SIGNALLED;
390 status->value.integer = gdb_signal_from_host (WTERMSIG (wstat));
391 lynx_debug ("process terminated with code: %d",
392 status->value.integer);
393 }
394 else
395 {
396 /* Not sure what happened if we get here, or whether we can
397 in fact get here. But if we do, handle the event the best
398 we can. */
399 status->kind = TARGET_WAITKIND_STOPPED;
400 status->value.integer = gdb_signal_from_host (0);
401 lynx_debug ("unknown event ????");
402 }
403
404 /* SIGTRAP events are generated for situations other than single-step/
405 breakpoint events (Eg. new-thread events). Handle those other types
406 of events, and resume the execution if necessary. */
407 if (status->kind == TARGET_WAITKIND_STOPPED
408 && status->value.integer == GDB_SIGNAL_TRAP)
409 {
410 const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);
411
412 lynx_debug ("(realsig = %d)", realsig);
413 switch (realsig)
414 {
415 case SIGNEWTHREAD:
416 /* We just added the new thread above. No need to do anything
417 further. Just resume the execution again. */
418 lynx_continue (new_ptid);
419 goto retry;
420
421 case SIGTHREADEXIT:
422 remove_thread (find_thread_ptid (new_ptid));
423 lynx_continue (new_ptid);
424 goto retry;
425 }
426 }
427
428 return new_ptid;
429 }
430
431 /* A wrapper around lynx_wait_1 that also prints debug traces when
432 such debug traces have been activated. */
433
434 static ptid_t
lynx_wait(ptid_t ptid,struct target_waitstatus * status,int options)435 lynx_wait (ptid_t ptid, struct target_waitstatus *status, int options)
436 {
437 ptid_t new_ptid;
438
439 lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
440 lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
441 new_ptid = lynx_wait_1 (ptid, status, options);
442 lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)",
443 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid),
444 status->kind);
445 return new_ptid;
446 }
447
448 /* Implement the kill target_ops method. */
449
450 static int
lynx_kill(int pid)451 lynx_kill (int pid)
452 {
453 ptid_t ptid = lynx_ptid_build (pid, 0);
454 struct target_waitstatus status;
455 struct process_info *process;
456
457 process = find_process_pid (pid);
458 if (process == NULL)
459 return -1;
460
461 lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0);
462 lynx_wait (ptid, &status, 0);
463 the_target->mourn (process);
464 return 0;
465 }
466
467 /* Implement the detach target_ops method. */
468
469 static int
lynx_detach(int pid)470 lynx_detach (int pid)
471 {
472 ptid_t ptid = lynx_ptid_build (pid, 0);
473 struct process_info *process;
474
475 process = find_process_pid (pid);
476 if (process == NULL)
477 return -1;
478
479 lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0);
480 the_target->mourn (process);
481 return 0;
482 }
483
484 /* Implement the mourn target_ops method. */
485
486 static void
lynx_mourn(struct process_info * proc)487 lynx_mourn (struct process_info *proc)
488 {
489 lynx_clear_inferiors ();
490 }
491
492 /* Implement the join target_ops method. */
493
494 static void
lynx_join(int pid)495 lynx_join (int pid)
496 {
497 /* The PTRACE_DETACH is sufficient to detach from the process.
498 So no need to do anything extra. */
499 }
500
501 /* Implement the thread_alive target_ops method. */
502
503 static int
lynx_thread_alive(ptid_t ptid)504 lynx_thread_alive (ptid_t ptid)
505 {
506 /* The list of threads is updated at the end of each wait, so it
507 should be up to date. No need to re-fetch it. */
508 return (find_thread_ptid (ptid) != NULL);
509 }
510
511 /* Implement the fetch_registers target_ops method. */
512
513 static void
lynx_fetch_registers(struct regcache * regcache,int regno)514 lynx_fetch_registers (struct regcache *regcache, int regno)
515 {
516 struct lynx_regset_info *regset = lynx_target_regsets;
517 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
518
519 lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
520
521 while (regset->size >= 0)
522 {
523 char *buf;
524 int res;
525
526 buf = xmalloc (regset->size);
527 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
528 if (res < 0)
529 perror ("ptrace");
530 regset->store_function (regcache, buf);
531 free (buf);
532 regset++;
533 }
534 }
535
536 /* Implement the store_registers target_ops method. */
537
538 static void
lynx_store_registers(struct regcache * regcache,int regno)539 lynx_store_registers (struct regcache *regcache, int regno)
540 {
541 struct lynx_regset_info *regset = lynx_target_regsets;
542 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
543
544 lynx_debug ("lynx_store_registers (regno = %d)", regno);
545
546 while (regset->size >= 0)
547 {
548 char *buf;
549 int res;
550
551 buf = xmalloc (regset->size);
552 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
553 if (res == 0)
554 {
555 /* Then overlay our cached registers on that. */
556 regset->fill_function (regcache, buf);
557 /* Only now do we write the register set. */
558 res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf,
559 0, 0);
560 }
561 if (res < 0)
562 perror ("ptrace");
563 free (buf);
564 regset++;
565 }
566 }
567
568 /* Implement the read_memory target_ops method. */
569
570 static int
lynx_read_memory(CORE_ADDR memaddr,unsigned char * myaddr,int len)571 lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
572 {
573 /* On LynxOS, memory reads needs to be performed in chunks the size
574 of int types, and they should also be aligned accordingly. */
575 int buf;
576 const int xfer_size = sizeof (buf);
577 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
578 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
579
580 while (addr < memaddr + len)
581 {
582 int skip = 0;
583 int truncate = 0;
584
585 errno = 0;
586 if (addr < memaddr)
587 skip = memaddr - addr;
588 if (addr + xfer_size > memaddr + len)
589 truncate = addr + xfer_size - memaddr - len;
590 buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
591 if (errno)
592 return errno;
593 memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip,
594 xfer_size - skip - truncate);
595 addr += xfer_size;
596 }
597
598 return 0;
599 }
600
601 /* Implement the write_memory target_ops method. */
602
603 static int
lynx_write_memory(CORE_ADDR memaddr,const unsigned char * myaddr,int len)604 lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
605 {
606 /* On LynxOS, memory writes needs to be performed in chunks the size
607 of int types, and they should also be aligned accordingly. */
608 int buf;
609 const int xfer_size = sizeof (buf);
610 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
611 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
612
613 while (addr < memaddr + len)
614 {
615 int skip = 0;
616 int truncate = 0;
617
618 if (addr < memaddr)
619 skip = memaddr - addr;
620 if (addr + xfer_size > memaddr + len)
621 truncate = addr + xfer_size - memaddr - len;
622 if (skip > 0 || truncate > 0)
623 /* We need to read the memory at this address in order to preserve
624 the data that we are not overwriting. */
625 lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
626 if (errno)
627 return errno;
628 memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
629 xfer_size - skip - truncate);
630 errno = 0;
631 lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
632 if (errno)
633 return errno;
634 addr += xfer_size;
635 }
636
637 return 0;
638 }
639
640 /* Implement the kill_request target_ops method. */
641
642 static void
lynx_request_interrupt(void)643 lynx_request_interrupt (void)
644 {
645 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
646
647 kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
648 }
649
650 /* The LynxOS target_ops vector. */
651
652 static struct target_ops lynx_target_ops = {
653 lynx_create_inferior,
654 lynx_attach,
655 lynx_kill,
656 lynx_detach,
657 lynx_mourn,
658 lynx_join,
659 lynx_thread_alive,
660 lynx_resume,
661 lynx_wait,
662 lynx_fetch_registers,
663 lynx_store_registers,
664 NULL, /* prepare_to_access_memory */
665 NULL, /* done_accessing_memory */
666 lynx_read_memory,
667 lynx_write_memory,
668 NULL, /* look_up_symbols */
669 lynx_request_interrupt,
670 NULL, /* read_auxv */
671 NULL, /* insert_point */
672 NULL, /* remove_point */
673 NULL, /* stopped_by_watchpoint */
674 NULL, /* stopped_data_address */
675 NULL, /* read_offsets */
676 NULL, /* get_tls_address */
677 NULL, /* qxfer_spu */
678 NULL, /* hostio_last_error */
679 NULL, /* qxfer_osdata */
680 NULL, /* qxfer_siginfo */
681 NULL, /* supports_non_stop */
682 NULL, /* async */
683 NULL, /* start_non_stop */
684 NULL, /* supports_multi_process */
685 NULL, /* handle_monitor_command */
686 };
687
688 void
initialize_low(void)689 initialize_low (void)
690 {
691 set_target_ops (&lynx_target_ops);
692 the_low_target.arch_setup ();
693 }
694
695