1/* Copyright (C) 2009, 2010, 2011 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 <sys/wait.h>
29#include <signal.h>
30
31int using_threads = 1;
32
33/* Print a debug trace on standard output if debug_threads is set.  */
34
35static void
36lynx_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
52static ptid_t
53lynx_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
69static int
70lynx_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
77static long
78lynx_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
88static int
89lynx_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
96static char *
97ptrace_request_to_str (int request)
98{
99  switch (request)
100    {
101      case PTRACE_TRACEME:
102        return "PTRACE_TRACEME";
103        break;
104      case PTRACE_PEEKTEXT:
105        return "PTRACE_PEEKTEXT";
106        break;
107      case PTRACE_PEEKDATA:
108        return "PTRACE_PEEKDATA";
109        break;
110      case PTRACE_PEEKUSER:
111        return "PTRACE_PEEKUSER";
112        break;
113      case PTRACE_POKETEXT:
114        return "PTRACE_POKETEXT";
115        break;
116      case PTRACE_POKEDATA:
117        return "PTRACE_POKEDATA";
118        break;
119      case PTRACE_POKEUSER:
120        return "PTRACE_POKEUSER";
121        break;
122      case PTRACE_CONT:
123        return "PTRACE_CONT";
124        break;
125      case PTRACE_KILL:
126        return "PTRACE_KILL";
127        break;
128      case PTRACE_SINGLESTEP:
129        return "PTRACE_SINGLESTEP";
130        break;
131      case PTRACE_ATTACH:
132        return "PTRACE_ATTACH";
133        break;
134      case PTRACE_DETACH:
135        return "PTRACE_DETACH";
136        break;
137      case PTRACE_GETREGS:
138        return "PTRACE_GETREGS";
139        break;
140      case PTRACE_SETREGS:
141        return "PTRACE_SETREGS";
142        break;
143      case PTRACE_GETFPREGS:
144        return "PTRACE_GETFPREGS";
145        break;
146      case PTRACE_SETFPREGS:
147        return "PTRACE_SETFPREGS";
148        break;
149      case PTRACE_READDATA:
150        return "PTRACE_READDATA";
151        break;
152      case PTRACE_WRITEDATA:
153        return "PTRACE_WRITEDATA";
154        break;
155      case PTRACE_READTEXT:
156        return "PTRACE_READTEXT";
157        break;
158      case PTRACE_WRITETEXT:
159        return "PTRACE_WRITETEXT";
160        break;
161      case PTRACE_GETFPAREGS:
162        return "PTRACE_GETFPAREGS";
163        break;
164      case PTRACE_SETFPAREGS:
165        return "PTRACE_SETFPAREGS";
166        break;
167      case PTRACE_GETWINDOW:
168        return "PTRACE_GETWINDOW";
169        break;
170      case PTRACE_SETWINDOW:
171        return "PTRACE_SETWINDOW";
172        break;
173      case PTRACE_SYSCALL:
174        return "PTRACE_SYSCALL";
175        break;
176      case PTRACE_DUMPCORE:
177        return "PTRACE_DUMPCORE";
178        break;
179      case PTRACE_SETWRBKPT:
180        return "PTRACE_SETWRBKPT";
181        break;
182      case PTRACE_SETACBKPT:
183        return "PTRACE_SETACBKPT";
184        break;
185      case PTRACE_CLRBKPT:
186        return "PTRACE_CLRBKPT";
187        break;
188      case PTRACE_GET_UCODE:
189        return "PTRACE_GET_UCODE";
190        break;
191#ifdef PT_READ_GPR
192      case PT_READ_GPR:
193        return "PT_READ_GPR";
194        break;
195#endif
196#ifdef PT_WRITE_GPR
197      case PT_WRITE_GPR:
198        return "PT_WRITE_GPR";
199        break;
200#endif
201#ifdef PT_READ_FPR
202      case PT_READ_FPR:
203        return "PT_READ_FPR";
204        break;
205#endif
206#ifdef PT_WRITE_FPR
207      case PT_WRITE_FPR:
208        return "PT_WRITE_FPR";
209        break;
210#endif
211#ifdef PT_READ_VPR
212      case PT_READ_VPR:
213        return "PT_READ_VPR";
214        break;
215#endif
216#ifdef PT_WRITE_VPR
217      case PT_WRITE_VPR:
218        return "PT_WRITE_VPR";
219        break;
220#endif
221#ifdef PTRACE_PEEKUSP
222      case PTRACE_PEEKUSP:
223        return "PTRACE_PEEKUSP";
224        break;
225#endif
226#ifdef PTRACE_POKEUSP
227      case PTRACE_POKEUSP:
228        return "PTRACE_POKEUSP";
229        break;
230#endif
231      case PTRACE_PEEKTHREAD:
232        return "PTRACE_PEEKTHREAD";
233        break;
234      case PTRACE_THREADUSER:
235        return "PTRACE_THREADUSER";
236        break;
237      case PTRACE_FPREAD:
238        return "PTRACE_FPREAD";
239        break;
240      case PTRACE_FPWRITE:
241        return "PTRACE_FPWRITE";
242        break;
243      case PTRACE_SETSIG:
244        return "PTRACE_SETSIG";
245        break;
246      case PTRACE_CONT_ONE:
247        return "PTRACE_CONT_ONE";
248        break;
249      case PTRACE_KILL_ONE:
250        return "PTRACE_KILL_ONE";
251        break;
252      case PTRACE_SINGLESTEP_ONE:
253        return "PTRACE_SINGLESTEP_ONE";
254        break;
255      case PTRACE_GETLOADINFO:
256        return "PTRACE_GETLOADINFO";
257        break;
258      case PTRACE_GETTHREADLIST:
259        return "PTRACE_GETTHREADLIST";
260        break;
261    }
262  return "<unknown-request>";
263}
264
265/* A wrapper around ptrace that allows us to print debug traces of
266   ptrace calls if debug traces are activated.  */
267
268static int
269lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
270{
271  int result;
272  const int pid = lynx_ptrace_pid_from_ptid (ptid);
273  int saved_errno;
274
275  if (debug_threads)
276    fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
277             "data=0x%x, addr2=0x%x)",
278             ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid),
279             addr, data, addr2);
280  result = ptrace (request, pid, addr, data, addr2);
281  saved_errno = errno;
282  if (debug_threads)
283    fprintf (stderr, " -> %d (=0x%x)\n", result, result);
284
285  errno = saved_errno;
286  return result;
287}
288
289/* Implement the create_inferior method of the target_ops vector.  */
290
291static int
292lynx_create_inferior (char *program, char **allargs)
293{
294  struct process_info *new_process;
295  int pid;
296
297  lynx_debug ("lynx_create_inferior ()");
298
299  pid = fork ();
300  if (pid < 0)
301    perror_with_name ("fork");
302
303  if (pid == 0)
304    {
305      int pgrp;
306
307      /* Switch child to its own process group so that signals won't
308         directly affect gdbserver. */
309      pgrp = getpid();
310      setpgid (0, pgrp);
311      ioctl (0, TIOCSPGRP, &pgrp);
312      lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
313      execv (program, allargs);
314      fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
315      fflush (stderr);
316      _exit (0177);
317    }
318
319  new_process = add_process (pid, 0);
320  /* Do not add the process thread just yet, as we do not know its tid.
321     We will add it later, during the wait for the STOP event corresponding
322     to the lynx_ptrace (PTRACE_TRACEME) call above.  */
323  return pid;
324}
325
326/* Implement the attach target_ops method.  */
327
328static int
329lynx_attach (unsigned long pid)
330{
331  struct process_info *new_process;
332  ptid_t ptid = lynx_ptid_build (pid, 0);
333
334  if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
335    error ("Cannot attach to process %lu: %s (%d)\n", pid,
336	   strerror (errno), errno);
337
338  new_process = add_process (pid, 1);
339  add_thread (ptid, NULL);
340
341  return 0;
342}
343
344/* Implement the resume target_ops method.  */
345
346static void
347lynx_resume (struct thread_resume *resume_info, size_t n)
348{
349  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
350  /* FIXME: Assume for now that n == 1.  */
351  const int request = (resume_info[0].kind == resume_step
352                       ? PTRACE_SINGLESTEP : PTRACE_CONT);
353  const int signal = resume_info[0].sig;
354  int ret;
355
356  regcache_invalidate ();
357  ret = lynx_ptrace (request, inferior_ptid, 1, signal, 0);
358}
359
360/* Resume the execution of the given PTID.  */
361
362static void
363lynx_continue (ptid_t ptid)
364{
365  struct thread_resume resume_info;
366
367  resume_info.thread = ptid;
368  resume_info.kind = resume_continue;
369  resume_info.sig = 0;
370
371  lynx_resume (&resume_info, 1);
372}
373
374/* Remove all inferiors and associated threads.  */
375
376static void
377lynx_clear_inferiors (void)
378{
379  /* We do not use private data, so nothing much to do except calling
380     clear_inferiors.  */
381  clear_inferiors ();
382}
383
384/* A wrapper around waitpid that handles the various idiosyncrasies
385   of LynxOS' waitpid.  */
386
387static int
388lynx_waitpid (int pid, int *stat_loc)
389{
390  int ret = 0;
391
392  while (1)
393    {
394      ret = waitpid (pid, stat_loc, WNOHANG);
395      if (ret < 0)
396        {
397	  /* An ECHILD error is not indicative of a real problem.
398	     It happens for instance while waiting for the inferior
399	     to stop after attaching to it.  */
400	  if (errno != ECHILD)
401	    perror_with_name ("waitpid (WNOHANG)");
402	}
403      if (ret > 0)
404        break;
405      /* No event with WNOHANG.  See if there is one with WUNTRACED.  */
406      ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED);
407      if (ret < 0)
408        {
409	  /* An ECHILD error is not indicative of a real problem.
410	     It happens for instance while waiting for the inferior
411	     to stop after attaching to it.  */
412	  if (errno != ECHILD)
413	    perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
414	}
415      if (ret > 0)
416        break;
417      usleep (1000);
418    }
419  return ret;
420}
421
422/* Implement the wait target_ops method.  */
423
424static ptid_t
425lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
426{
427  int pid;
428  int ret;
429  int wstat;
430  ptid_t new_ptid;
431
432  if (ptid_equal (ptid, minus_one_ptid))
433    pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior));
434  else
435    pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
436
437retry:
438
439  ret = lynx_waitpid (pid, &wstat);
440  new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
441
442  /* If this is a new thread, then add it now.  The reason why we do
443     this here instead of when handling new-thread events is because
444     we need to add the thread associated to the "main" thread - even
445     for non-threaded applications where the new-thread events are not
446     generated.  */
447  if (!find_thread_ptid (new_ptid))
448    add_thread (new_ptid, NULL);
449
450  if (WIFSTOPPED (wstat))
451    {
452      status->kind = TARGET_WAITKIND_STOPPED;
453      status->value.integer = target_signal_from_host (WSTOPSIG (wstat));
454      lynx_debug ("process stopped with signal: %d",
455                  status->value.integer);
456    }
457  else if (WIFEXITED (wstat))
458    {
459      status->kind = TARGET_WAITKIND_EXITED;
460      status->value.integer = WEXITSTATUS (wstat);
461      lynx_debug ("process exited with code: %d", status->value.integer);
462    }
463  else if (WIFSIGNALED (wstat))
464    {
465      status->kind = TARGET_WAITKIND_SIGNALLED;
466      status->value.integer = target_signal_from_host (WTERMSIG (wstat));
467      lynx_debug ("process terminated with code: %d",
468                  status->value.integer);
469    }
470  else
471    {
472      /* Not sure what happened if we get here, or whether we can
473	 in fact get here.  But if we do, handle the event the best
474	 we can.  */
475      status->kind = TARGET_WAITKIND_STOPPED;
476      status->value.integer = target_signal_from_host (0);
477      lynx_debug ("unknown event ????");
478    }
479
480  /* SIGTRAP events are generated for situations other than single-step/
481     breakpoint events (Eg. new-thread events).  Handle those other types
482     of events, and resume the execution if necessary.  */
483  if (status->kind == TARGET_WAITKIND_STOPPED
484      && status->value.integer == TARGET_SIGNAL_TRAP)
485    {
486      const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);
487
488      lynx_debug ("(realsig = %d)", realsig);
489      switch (realsig)
490	{
491	  case SIGNEWTHREAD:
492	    /* We just added the new thread above.  No need to do anything
493	       further.  Just resume the execution again.  */
494	    lynx_continue (ptid);
495	    goto retry;
496
497	  case SIGTHREADEXIT:
498	    remove_thread (find_thread_ptid (new_ptid));
499	    lynx_continue (ptid);
500	    goto retry;
501	}
502    }
503
504  return new_ptid;
505}
506
507/* A wrapper around lynx_wait_1 that also prints debug traces when
508   such debug traces have been activated.  */
509
510static ptid_t
511lynx_wait (ptid_t ptid, struct target_waitstatus *status, int options)
512{
513  ptid_t new_ptid;
514
515  lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
516              lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
517  new_ptid = lynx_wait_1 (ptid, status, options);
518  lynx_debug ("          -> (pid=%d, tid=%ld, status->kind = %d)",
519	      lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid),
520	      status->kind);
521  return new_ptid;
522}
523
524/* Implement the kill target_ops method.  */
525
526static int
527lynx_kill (int pid)
528{
529  ptid_t ptid = lynx_ptid_build (pid, 0);
530  struct target_waitstatus status;
531  struct process_info *process;
532
533  process = find_process_pid (pid);
534  if (process == NULL)
535    return -1;
536
537  lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0);
538  lynx_wait (ptid, &status, 0);
539  the_target->mourn (process);
540  return 0;
541}
542
543/* Implement the detach target_ops method.  */
544
545static int
546lynx_detach (int pid)
547{
548  ptid_t ptid = lynx_ptid_build (pid, 0);
549  struct process_info *process;
550
551  process = find_process_pid (pid);
552  if (process == NULL)
553    return -1;
554
555  lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0);
556  the_target->mourn (process);
557  return 0;
558}
559
560/* Implement the mourn target_ops method.  */
561
562static void
563lynx_mourn (struct process_info *proc)
564{
565  lynx_clear_inferiors ();
566}
567
568/* Implement the join target_ops method.  */
569
570static void
571lynx_join (int pid)
572{
573  /* The PTRACE_DETACH is sufficient to detach from the process.
574     So no need to do anything extra.  */
575}
576
577/* Implement the thread_alive target_ops method.  */
578
579static int
580lynx_thread_alive (ptid_t ptid)
581{
582  /* The list of threads is updated at the end of each wait, so it
583     should be up to date.  No need to re-fetch it.  */
584  return (find_thread_ptid (ptid) != NULL);
585}
586
587/* Implement the fetch_registers target_ops method.  */
588
589static void
590lynx_fetch_registers (struct regcache *regcache, int regno)
591{
592  struct lynx_regset_info *regset = lynx_target_regsets;
593  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
594
595  lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
596
597  while (regset->size >= 0)
598    {
599      char *buf;
600      int res;
601
602      buf = xmalloc (regset->size);
603      res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
604      if (res < 0)
605        perror ("ptrace");
606      regset->store_function (regcache, buf);
607      free (buf);
608      regset++;
609    }
610}
611
612/* Implement the store_registers target_ops method.  */
613
614static void
615lynx_store_registers (struct regcache *regcache, int regno)
616{
617  struct lynx_regset_info *regset = lynx_target_regsets;
618  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
619
620  lynx_debug ("lynx_store_registers (regno = %d)", regno);
621
622  while (regset->size >= 0)
623    {
624      char *buf;
625      int res;
626
627      buf = xmalloc (regset->size);
628      res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
629      if (res == 0)
630        {
631	  /* Then overlay our cached registers on that.  */
632	  regset->fill_function (regcache, buf);
633	  /* Only now do we write the register set.  */
634	  res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf,
635			     0, 0);
636        }
637      if (res < 0)
638        perror ("ptrace");
639      free (buf);
640      regset++;
641    }
642}
643
644/* Implement the read_memory target_ops method.  */
645
646static int
647lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
648{
649  /* On LynxOS, memory reads needs to be performed in chunks the size
650     of int types, and they should also be aligned accordingly.  */
651  int buf;
652  const int xfer_size = sizeof (buf);
653  CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
654  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
655
656  while (addr < memaddr + len)
657    {
658      int skip = 0;
659      int truncate = 0;
660
661      errno = 0;
662      if (addr < memaddr)
663        skip = memaddr - addr;
664      if (addr + xfer_size > memaddr + len)
665        truncate = addr + xfer_size - memaddr - len;
666      buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
667      if (errno)
668        return errno;
669      memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip,
670              xfer_size - skip - truncate);
671      addr += xfer_size;
672    }
673
674  return 0;
675}
676
677/* Implement the write_memory target_ops method.  */
678
679static int
680lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
681{
682  /* On LynxOS, memory writes needs to be performed in chunks the size
683     of int types, and they should also be aligned accordingly.  */
684  int buf;
685  const int xfer_size = sizeof (buf);
686  CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
687  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
688
689  while (addr < memaddr + len)
690    {
691      int skip = 0;
692      int truncate = 0;
693
694      if (addr < memaddr)
695        skip = memaddr - addr;
696      if (addr + xfer_size > memaddr + len)
697        truncate = addr + xfer_size - memaddr - len;
698      if (skip > 0 || truncate > 0)
699        /* We need to read the memory at this address in order to preserve
700           the data that we are not overwriting.  */
701        lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
702        if (errno)
703          return errno;
704      memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
705              xfer_size - skip - truncate);
706      errno = 0;
707      lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
708      if (errno)
709        return errno;
710      addr += xfer_size;
711    }
712
713  return 0;
714}
715
716/* Implement the kill_request target_ops method.  */
717
718static void
719lynx_request_interrupt (void)
720{
721  ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
722
723  kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
724}
725
726/* The LynxOS target_ops vector.  */
727
728static struct target_ops lynx_target_ops = {
729  lynx_create_inferior,
730  lynx_attach,
731  lynx_kill,
732  lynx_detach,
733  lynx_mourn,
734  lynx_join,
735  lynx_thread_alive,
736  lynx_resume,
737  lynx_wait,
738  lynx_fetch_registers,
739  lynx_store_registers,
740  NULL,  /* prepare_to_access_memory */
741  NULL,  /* done_accessing_memory */
742  lynx_read_memory,
743  lynx_write_memory,
744  NULL,  /* look_up_symbols */
745  lynx_request_interrupt,
746  NULL,  /* read_auxv */
747  NULL,  /* insert_point */
748  NULL,  /* remove_point */
749  NULL,  /* stopped_by_watchpoint */
750  NULL,  /* stopped_data_address */
751  NULL,  /* read_offsets */
752  NULL,  /* get_tls_address */
753  NULL,  /* qxfer_spu */
754  NULL,  /* hostio_last_error */
755  NULL,  /* qxfer_osdata */
756  NULL,  /* qxfer_siginfo */
757  NULL,  /* supports_non_stop */
758  NULL,  /* async */
759  NULL,  /* start_non_stop */
760  NULL,  /* supports_multi_process */
761  NULL,  /* handle_monitor_command */
762};
763
764void
765initialize_low (void)
766{
767  set_target_ops (&lynx_target_ops);
768  the_low_target.arch_setup ();
769}
770
771