1 /* Copyright (C) 2009-2013 Free Software Foundation, Inc.
3 This file is part of GDB.
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.
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.
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/>. */
23 #include <sys/ptrace.h>
24 #include <sys/piddef.h> /* Provides PIDGET, TIDGET, BUILDPID, etc. */
26 #include <sys/ioctl.h>
27 #include <sys/types.h>
31 int using_threads = 1;
33 const struct target_desc *lynx_tdesc;
35 /* Per-process private data. */
37 struct process_info_private
39 /* The PTID obtained from the last wait performed on this process.
40 Initialized to null_ptid until the first wait is performed. */
41 ptid_t last_wait_event_ptid;
44 /* Print a debug trace on standard output if debug_threads is set. */
47 lynx_debug (char *string, ...)
54 va_start (args, string);
55 fprintf (stderr, "DEBUG(lynx): ");
56 vfprintf (stderr, string, args);
57 fprintf (stderr, "\n");
61 /* Build a ptid_t given a PID and a LynxOS TID. */
64 lynx_ptid_build (int pid, long tid)
66 /* brobecker/2010-06-21: It looks like the LWP field in ptids
67 should be distinct for each thread (see write_ptid where it
68 writes the thread ID from the LWP). So instead of storing
69 the LynxOS tid in the tid field of the ptid, we store it in
71 return ptid_build (pid, tid, 0);
74 /* Return the process ID of the given PTID.
76 This function has little reason to exist, it's just a wrapper around
77 ptid_get_pid. But since we have a getter function for the lynxos
78 ptid, it feels cleaner to have a getter for the pid as well. */
81 lynx_ptid_get_pid (ptid_t ptid)
83 return ptid_get_pid (ptid);
86 /* Return the LynxOS tid of the given PTID. */
89 lynx_ptid_get_tid (ptid_t ptid)
91 /* See lynx_ptid_build: The LynxOS tid is stored inside the lwp field
93 return ptid_get_lwp (ptid);
96 /* For a given PTID, return the associated PID as known by the LynxOS
100 lynx_ptrace_pid_from_ptid (ptid_t ptid)
102 return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
105 /* Return a string image of the ptrace REQUEST number. */
108 ptrace_request_to_str (int request)
110 #define CASE(X) case X: return #X
113 CASE(PTRACE_TRACEME);
114 CASE(PTRACE_PEEKTEXT);
115 CASE(PTRACE_PEEKDATA);
116 CASE(PTRACE_PEEKUSER);
117 CASE(PTRACE_POKETEXT);
118 CASE(PTRACE_POKEDATA);
119 CASE(PTRACE_POKEUSER);
122 CASE(PTRACE_SINGLESTEP);
125 CASE(PTRACE_GETREGS);
126 CASE(PTRACE_SETREGS);
127 CASE(PTRACE_GETFPREGS);
128 CASE(PTRACE_SETFPREGS);
129 CASE(PTRACE_READDATA);
130 CASE(PTRACE_WRITEDATA);
131 CASE(PTRACE_READTEXT);
132 CASE(PTRACE_WRITETEXT);
133 CASE(PTRACE_GETFPAREGS);
134 CASE(PTRACE_SETFPAREGS);
135 CASE(PTRACE_GETWINDOW);
136 CASE(PTRACE_SETWINDOW);
137 CASE(PTRACE_SYSCALL);
138 CASE(PTRACE_DUMPCORE);
139 CASE(PTRACE_SETWRBKPT);
140 CASE(PTRACE_SETACBKPT);
141 CASE(PTRACE_CLRBKPT);
142 CASE(PTRACE_GET_UCODE);
161 #ifdef PTRACE_PEEKUSP
162 CASE(PTRACE_PEEKUSP);
164 #ifdef PTRACE_POKEUSP
165 CASE(PTRACE_POKEUSP);
167 CASE(PTRACE_PEEKTHREAD);
168 CASE(PTRACE_THREADUSER);
170 CASE(PTRACE_FPWRITE);
172 CASE(PTRACE_CONT_ONE);
173 CASE(PTRACE_KILL_ONE);
174 CASE(PTRACE_SINGLESTEP_ONE);
175 CASE(PTRACE_GETLOADINFO);
176 CASE(PTRACE_GETTRACESIG);
177 #ifdef PTRACE_GETTHREADLIST
178 CASE(PTRACE_GETTHREADLIST);
183 return "<unknown-request>";
186 /* A wrapper around ptrace that allows us to print debug traces of
187 ptrace calls if debug traces are activated. */
190 lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
193 const int pid = lynx_ptrace_pid_from_ptid (ptid);
197 fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
198 "data=0x%x, addr2=0x%x)",
199 ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid),
201 result = ptrace (request, pid, addr, data, addr2);
204 fprintf (stderr, " -> %d (=0x%x)\n", result, result);
210 /* Call add_process with the given parameters, and initializes
211 the process' private data. */
213 static struct process_info *
214 lynx_add_process (int pid, int attached)
216 struct process_info *proc;
218 proc = add_process (pid, attached);
219 proc->tdesc = lynx_tdesc;
220 proc->private = xcalloc (1, sizeof (*proc->private));
221 proc->private->last_wait_event_ptid = null_ptid;
226 /* Implement the create_inferior method of the target_ops vector. */
229 lynx_create_inferior (char *program, char **allargs)
233 lynx_debug ("lynx_create_inferior ()");
237 perror_with_name ("fork");
243 /* Switch child to its own process group so that signals won't
244 directly affect gdbserver. */
247 ioctl (0, TIOCSPGRP, &pgrp);
248 lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
249 execv (program, allargs);
250 fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
255 lynx_add_process (pid, 0);
256 /* Do not add the process thread just yet, as we do not know its tid.
257 We will add it later, during the wait for the STOP event corresponding
258 to the lynx_ptrace (PTRACE_TRACEME) call above. */
262 /* Implement the attach target_ops method. */
265 lynx_attach (unsigned long pid)
267 ptid_t ptid = lynx_ptid_build (pid, 0);
269 if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
270 error ("Cannot attach to process %lu: %s (%d)\n", pid,
271 strerror (errno), errno);
273 lynx_add_process (pid, 1);
274 add_thread (ptid, NULL);
279 /* Implement the resume target_ops method. */
282 lynx_resume (struct thread_resume *resume_info, size_t n)
284 /* FIXME: Assume for now that n == 1. */
285 ptid_t ptid = resume_info[0].thread;
286 const int request = (resume_info[0].kind == resume_step
287 ? PTRACE_SINGLESTEP : PTRACE_CONT);
288 const int signal = resume_info[0].sig;
290 /* If given a minus_one_ptid, then try using the current_process'
291 private->last_wait_event_ptid. On most LynxOS versions,
292 using any of the process' thread works well enough, but
293 LynxOS 178 is a little more sensitive, and triggers some
294 unexpected signals (Eg SIG61) when we resume the inferior
295 using a different thread. */
296 if (ptid_equal (ptid, minus_one_ptid))
297 ptid = current_process()->private->last_wait_event_ptid;
299 /* The ptid might still be minus_one_ptid; this can happen between
300 the moment we create the inferior or attach to a process, and
301 the moment we resume its execution for the first time. It is
302 fine to use the current_inferior's ptid in those cases. */
303 if (ptid_equal (ptid, minus_one_ptid))
304 ptid = thread_to_gdb_id (current_inferior);
306 regcache_invalidate ();
309 lynx_ptrace (request, ptid, 1, signal, 0);
311 perror_with_name ("ptrace");
314 /* Resume the execution of the given PTID. */
317 lynx_continue (ptid_t ptid)
319 struct thread_resume resume_info;
321 resume_info.thread = ptid;
322 resume_info.kind = resume_continue;
325 lynx_resume (&resume_info, 1);
328 /* A wrapper around waitpid that handles the various idiosyncrasies
329 of LynxOS' waitpid. */
332 lynx_waitpid (int pid, int *stat_loc)
338 ret = waitpid (pid, stat_loc, WNOHANG);
341 /* An ECHILD error is not indicative of a real problem.
342 It happens for instance while waiting for the inferior
343 to stop after attaching to it. */
345 perror_with_name ("waitpid (WNOHANG)");
349 /* No event with WNOHANG. See if there is one with WUNTRACED. */
350 ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED);
353 /* An ECHILD error is not indicative of a real problem.
354 It happens for instance while waiting for the inferior
355 to stop after attaching to it. */
357 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
366 /* Implement the wait target_ops method. */
369 lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
376 if (ptid_equal (ptid, minus_one_ptid))
377 pid = lynx_ptid_get_pid (thread_to_gdb_id (current_inferior));
379 pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
383 ret = lynx_waitpid (pid, &wstat);
384 new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
385 find_process_pid (ret)->private->last_wait_event_ptid = new_ptid;
387 /* If this is a new thread, then add it now. The reason why we do
388 this here instead of when handling new-thread events is because
389 we need to add the thread associated to the "main" thread - even
390 for non-threaded applications where the new-thread events are not
392 if (!find_thread_ptid (new_ptid))
394 lynx_debug ("New thread: (pid = %d, tid = %d)",
395 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
396 add_thread (new_ptid, NULL);
399 if (WIFSTOPPED (wstat))
401 status->kind = TARGET_WAITKIND_STOPPED;
402 status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat));
403 lynx_debug ("process stopped with signal: %d",
404 status->value.integer);
406 else if (WIFEXITED (wstat))
408 status->kind = TARGET_WAITKIND_EXITED;
409 status->value.integer = WEXITSTATUS (wstat);
410 lynx_debug ("process exited with code: %d", status->value.integer);
412 else if (WIFSIGNALED (wstat))
414 status->kind = TARGET_WAITKIND_SIGNALLED;
415 status->value.integer = gdb_signal_from_host (WTERMSIG (wstat));
416 lynx_debug ("process terminated with code: %d",
417 status->value.integer);
421 /* Not sure what happened if we get here, or whether we can
422 in fact get here. But if we do, handle the event the best
424 status->kind = TARGET_WAITKIND_STOPPED;
425 status->value.integer = gdb_signal_from_host (0);
426 lynx_debug ("unknown event ????");
429 /* SIGTRAP events are generated for situations other than single-step/
430 breakpoint events (Eg. new-thread events). Handle those other types
431 of events, and resume the execution if necessary. */
432 if (status->kind == TARGET_WAITKIND_STOPPED
433 && status->value.integer == GDB_SIGNAL_TRAP)
435 const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);
437 lynx_debug ("(realsig = %d)", realsig);
441 /* We just added the new thread above. No need to do anything
442 further. Just resume the execution again. */
443 lynx_continue (new_ptid);
447 remove_thread (find_thread_ptid (new_ptid));
448 lynx_continue (new_ptid);
456 /* A wrapper around lynx_wait_1 that also prints debug traces when
457 such debug traces have been activated. */
460 lynx_wait (ptid_t ptid, struct target_waitstatus *status, int options)
464 lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
465 lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
466 new_ptid = lynx_wait_1 (ptid, status, options);
467 lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)",
468 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid),
473 /* Implement the kill target_ops method. */
478 ptid_t ptid = lynx_ptid_build (pid, 0);
479 struct target_waitstatus status;
480 struct process_info *process;
482 process = find_process_pid (pid);
486 lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0);
487 lynx_wait (ptid, &status, 0);
488 the_target->mourn (process);
492 /* Implement the detach target_ops method. */
495 lynx_detach (int pid)
497 ptid_t ptid = lynx_ptid_build (pid, 0);
498 struct process_info *process;
500 process = find_process_pid (pid);
504 lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0);
505 the_target->mourn (process);
509 /* Implement the mourn target_ops method. */
512 lynx_mourn (struct process_info *proc)
514 /* Free our private data. */
515 free (proc->private);
516 proc->private = NULL;
521 /* Implement the join target_ops method. */
526 /* The PTRACE_DETACH is sufficient to detach from the process.
527 So no need to do anything extra. */
530 /* Implement the thread_alive target_ops method. */
533 lynx_thread_alive (ptid_t ptid)
535 /* The list of threads is updated at the end of each wait, so it
536 should be up to date. No need to re-fetch it. */
537 return (find_thread_ptid (ptid) != NULL);
540 /* Implement the fetch_registers target_ops method. */
543 lynx_fetch_registers (struct regcache *regcache, int regno)
545 struct lynx_regset_info *regset = lynx_target_regsets;
546 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
548 lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
550 while (regset->size >= 0)
555 buf = xmalloc (regset->size);
556 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
559 regset->store_function (regcache, buf);
565 /* Implement the store_registers target_ops method. */
568 lynx_store_registers (struct regcache *regcache, int regno)
570 struct lynx_regset_info *regset = lynx_target_regsets;
571 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
573 lynx_debug ("lynx_store_registers (regno = %d)", regno);
575 while (regset->size >= 0)
580 buf = xmalloc (regset->size);
581 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
584 /* Then overlay our cached registers on that. */
585 regset->fill_function (regcache, buf);
586 /* Only now do we write the register set. */
587 res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf,
597 /* Implement the read_memory target_ops method. */
600 lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
602 /* On LynxOS, memory reads needs to be performed in chunks the size
603 of int types, and they should also be aligned accordingly. */
605 const int xfer_size = sizeof (buf);
606 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
607 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
609 while (addr < memaddr + len)
616 skip = memaddr - addr;
617 if (addr + xfer_size > memaddr + len)
618 truncate = addr + xfer_size - memaddr - len;
619 buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
622 memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip,
623 xfer_size - skip - truncate);
630 /* Implement the write_memory target_ops method. */
633 lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
635 /* On LynxOS, memory writes needs to be performed in chunks the size
636 of int types, and they should also be aligned accordingly. */
638 const int xfer_size = sizeof (buf);
639 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
640 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
642 while (addr < memaddr + len)
648 skip = memaddr - addr;
649 if (addr + xfer_size > memaddr + len)
650 truncate = addr + xfer_size - memaddr - len;
651 if (skip > 0 || truncate > 0)
652 /* We need to read the memory at this address in order to preserve
653 the data that we are not overwriting. */
654 lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
657 memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
658 xfer_size - skip - truncate);
660 lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
669 /* Implement the kill_request target_ops method. */
672 lynx_request_interrupt (void)
674 ptid_t inferior_ptid = thread_to_gdb_id (current_inferior);
676 kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
679 /* The LynxOS target_ops vector. */
681 static struct target_ops lynx_target_ops = {
682 lynx_create_inferior,
691 lynx_fetch_registers,
692 lynx_store_registers,
693 NULL, /* prepare_to_access_memory */
694 NULL, /* done_accessing_memory */
697 NULL, /* look_up_symbols */
698 lynx_request_interrupt,
699 NULL, /* read_auxv */
700 NULL, /* insert_point */
701 NULL, /* remove_point */
702 NULL, /* stopped_by_watchpoint */
703 NULL, /* stopped_data_address */
704 NULL, /* read_offsets */
705 NULL, /* get_tls_address */
706 NULL, /* qxfer_spu */
707 NULL, /* hostio_last_error */
708 NULL, /* qxfer_osdata */
709 NULL, /* qxfer_siginfo */
710 NULL, /* supports_non_stop */
712 NULL, /* start_non_stop */
713 NULL, /* supports_multi_process */
714 NULL, /* handle_monitor_command */
718 initialize_low (void)
720 set_target_ops (&lynx_target_ops);
721 the_low_target.arch_setup ();