1 /* Copyright (C) 2009-2015 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>
30 #include "filestuff.h"
32 int using_threads = 1;
34 const struct target_desc *lynx_tdesc;
36 /* Per-process private data. */
38 struct process_info_private
40 /* The PTID obtained from the last wait performed on this process.
41 Initialized to null_ptid until the first wait is performed. */
42 ptid_t last_wait_event_ptid;
45 /* Print a debug trace on standard output if debug_threads is set. */
48 lynx_debug (char *string, ...)
55 va_start (args, string);
56 fprintf (stderr, "DEBUG(lynx): ");
57 vfprintf (stderr, string, args);
58 fprintf (stderr, "\n");
62 /* Build a ptid_t given a PID and a LynxOS TID. */
65 lynx_ptid_build (int pid, long tid)
67 /* brobecker/2010-06-21: It looks like the LWP field in ptids
68 should be distinct for each thread (see write_ptid where it
69 writes the thread ID from the LWP). So instead of storing
70 the LynxOS tid in the tid field of the ptid, we store it in
72 return ptid_build (pid, tid, 0);
75 /* Return the process ID of the given PTID.
77 This function has little reason to exist, it's just a wrapper around
78 ptid_get_pid. But since we have a getter function for the lynxos
79 ptid, it feels cleaner to have a getter for the pid as well. */
82 lynx_ptid_get_pid (ptid_t ptid)
84 return ptid_get_pid (ptid);
87 /* Return the LynxOS tid of the given PTID. */
90 lynx_ptid_get_tid (ptid_t ptid)
92 /* See lynx_ptid_build: The LynxOS tid is stored inside the lwp field
94 return ptid_get_lwp (ptid);
97 /* For a given PTID, return the associated PID as known by the LynxOS
101 lynx_ptrace_pid_from_ptid (ptid_t ptid)
103 return BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
106 /* Return a string image of the ptrace REQUEST number. */
109 ptrace_request_to_str (int request)
111 #define CASE(X) case X: return #X
114 CASE(PTRACE_TRACEME);
115 CASE(PTRACE_PEEKTEXT);
116 CASE(PTRACE_PEEKDATA);
117 CASE(PTRACE_PEEKUSER);
118 CASE(PTRACE_POKETEXT);
119 CASE(PTRACE_POKEDATA);
120 CASE(PTRACE_POKEUSER);
123 CASE(PTRACE_SINGLESTEP);
126 CASE(PTRACE_GETREGS);
127 CASE(PTRACE_SETREGS);
128 CASE(PTRACE_GETFPREGS);
129 CASE(PTRACE_SETFPREGS);
130 CASE(PTRACE_READDATA);
131 CASE(PTRACE_WRITEDATA);
132 CASE(PTRACE_READTEXT);
133 CASE(PTRACE_WRITETEXT);
134 CASE(PTRACE_GETFPAREGS);
135 CASE(PTRACE_SETFPAREGS);
136 CASE(PTRACE_GETWINDOW);
137 CASE(PTRACE_SETWINDOW);
138 CASE(PTRACE_SYSCALL);
139 CASE(PTRACE_DUMPCORE);
140 CASE(PTRACE_SETWRBKPT);
141 CASE(PTRACE_SETACBKPT);
142 CASE(PTRACE_CLRBKPT);
143 CASE(PTRACE_GET_UCODE);
162 #ifdef PTRACE_PEEKUSP
163 CASE(PTRACE_PEEKUSP);
165 #ifdef PTRACE_POKEUSP
166 CASE(PTRACE_POKEUSP);
168 CASE(PTRACE_PEEKTHREAD);
169 CASE(PTRACE_THREADUSER);
171 CASE(PTRACE_FPWRITE);
173 CASE(PTRACE_CONT_ONE);
174 CASE(PTRACE_KILL_ONE);
175 CASE(PTRACE_SINGLESTEP_ONE);
176 CASE(PTRACE_GETLOADINFO);
177 CASE(PTRACE_GETTRACESIG);
178 #ifdef PTRACE_GETTHREADLIST
179 CASE(PTRACE_GETTHREADLIST);
184 return "<unknown-request>";
187 /* A wrapper around ptrace that allows us to print debug traces of
188 ptrace calls if debug traces are activated. */
191 lynx_ptrace (int request, ptid_t ptid, int addr, int data, int addr2)
194 const int pid = lynx_ptrace_pid_from_ptid (ptid);
198 fprintf (stderr, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
199 "data=0x%x, addr2=0x%x)",
200 ptrace_request_to_str (request), pid, PIDGET (pid), TIDGET (pid),
202 result = ptrace (request, pid, addr, data, addr2);
205 fprintf (stderr, " -> %d (=0x%x)\n", result, result);
211 /* Call add_process with the given parameters, and initializes
212 the process' private data. */
214 static struct process_info *
215 lynx_add_process (int pid, int attached)
217 struct process_info *proc;
219 proc = add_process (pid, attached);
220 proc->tdesc = lynx_tdesc;
221 proc->priv = XCNEW (struct process_info_private);
222 proc->priv->last_wait_event_ptid = null_ptid;
227 /* Implement the create_inferior method of the target_ops vector. */
230 lynx_create_inferior (char *program, char **allargs)
234 lynx_debug ("lynx_create_inferior ()");
238 perror_with_name ("fork");
246 /* Switch child to its own process group so that signals won't
247 directly affect gdbserver. */
250 ioctl (0, TIOCSPGRP, &pgrp);
251 lynx_ptrace (PTRACE_TRACEME, null_ptid, 0, 0, 0);
252 execv (program, allargs);
253 fprintf (stderr, "Cannot exec %s: %s.\n", program, strerror (errno));
258 lynx_add_process (pid, 0);
259 /* Do not add the process thread just yet, as we do not know its tid.
260 We will add it later, during the wait for the STOP event corresponding
261 to the lynx_ptrace (PTRACE_TRACEME) call above. */
265 /* Assuming we've just attached to a running inferior whose pid is PID,
266 add all threads running in that process. */
269 lynx_add_threads_after_attach (int pid)
271 /* Ugh! There appears to be no way to get the list of threads
272 in the program we just attached to. So get the list by calling
273 the "ps" command. This is only needed now, as we will then
274 keep the thread list up to date thanks to thread creation and
275 exit notifications. */
278 int thread_pid, thread_tid;
280 f = popen ("ps atx", "r");
282 perror_with_name ("Cannot get thread list");
284 while (fgets (buf, sizeof (buf), f) != NULL)
285 if ((sscanf (buf, "%d %d", &thread_pid, &thread_tid) == 2
286 && thread_pid == pid))
288 ptid_t thread_ptid = lynx_ptid_build (pid, thread_tid);
290 if (!find_thread_ptid (thread_ptid))
292 lynx_debug ("New thread: (pid = %d, tid = %d)",
294 add_thread (thread_ptid, NULL);
301 /* Implement the attach target_ops method. */
304 lynx_attach (unsigned long pid)
306 ptid_t ptid = lynx_ptid_build (pid, 0);
308 if (lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
309 error ("Cannot attach to process %lu: %s (%d)\n", pid,
310 strerror (errno), errno);
312 lynx_add_process (pid, 1);
313 lynx_add_threads_after_attach (pid);
318 /* Implement the resume target_ops method. */
321 lynx_resume (struct thread_resume *resume_info, size_t n)
323 ptid_t ptid = resume_info[0].thread;
325 = (resume_info[0].kind == resume_step
326 ? (n == 1 ? PTRACE_SINGLESTEP_ONE : PTRACE_SINGLESTEP)
328 const int signal = resume_info[0].sig;
330 /* If given a minus_one_ptid, then try using the current_process'
331 private->last_wait_event_ptid. On most LynxOS versions,
332 using any of the process' thread works well enough, but
333 LynxOS 178 is a little more sensitive, and triggers some
334 unexpected signals (Eg SIG61) when we resume the inferior
335 using a different thread. */
336 if (ptid_equal (ptid, minus_one_ptid))
337 ptid = current_process()->priv->last_wait_event_ptid;
339 /* The ptid might still be minus_one_ptid; this can happen between
340 the moment we create the inferior or attach to a process, and
341 the moment we resume its execution for the first time. It is
342 fine to use the current_thread's ptid in those cases. */
343 if (ptid_equal (ptid, minus_one_ptid))
344 ptid = thread_to_gdb_id (current_thread);
346 regcache_invalidate_pid (ptid_get_pid (ptid));
349 lynx_ptrace (request, ptid, 1, signal, 0);
351 perror_with_name ("ptrace");
354 /* Resume the execution of the given PTID. */
357 lynx_continue (ptid_t ptid)
359 struct thread_resume resume_info;
361 resume_info.thread = ptid;
362 resume_info.kind = resume_continue;
365 lynx_resume (&resume_info, 1);
368 /* A wrapper around waitpid that handles the various idiosyncrasies
369 of LynxOS' waitpid. */
372 lynx_waitpid (int pid, int *stat_loc)
378 ret = waitpid (pid, stat_loc, WNOHANG);
381 /* An ECHILD error is not indicative of a real problem.
382 It happens for instance while waiting for the inferior
383 to stop after attaching to it. */
385 perror_with_name ("waitpid (WNOHANG)");
389 /* No event with WNOHANG. See if there is one with WUNTRACED. */
390 ret = waitpid (pid, stat_loc, WNOHANG | WUNTRACED);
393 /* An ECHILD error is not indicative of a real problem.
394 It happens for instance while waiting for the inferior
395 to stop after attaching to it. */
397 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
406 /* Implement the wait target_ops method. */
409 lynx_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
416 if (ptid_equal (ptid, minus_one_ptid))
417 pid = lynx_ptid_get_pid (thread_to_gdb_id (current_thread));
419 pid = BUILDPID (lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
423 ret = lynx_waitpid (pid, &wstat);
424 new_ptid = lynx_ptid_build (ret, ((union wait *) &wstat)->w_tid);
425 find_process_pid (ret)->priv->last_wait_event_ptid = new_ptid;
427 /* If this is a new thread, then add it now. The reason why we do
428 this here instead of when handling new-thread events is because
429 we need to add the thread associated to the "main" thread - even
430 for non-threaded applications where the new-thread events are not
432 if (!find_thread_ptid (new_ptid))
434 lynx_debug ("New thread: (pid = %d, tid = %d)",
435 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid));
436 add_thread (new_ptid, NULL);
439 if (WIFSTOPPED (wstat))
441 status->kind = TARGET_WAITKIND_STOPPED;
442 status->value.integer = gdb_signal_from_host (WSTOPSIG (wstat));
443 lynx_debug ("process stopped with signal: %d",
444 status->value.integer);
446 else if (WIFEXITED (wstat))
448 status->kind = TARGET_WAITKIND_EXITED;
449 status->value.integer = WEXITSTATUS (wstat);
450 lynx_debug ("process exited with code: %d", status->value.integer);
452 else if (WIFSIGNALED (wstat))
454 status->kind = TARGET_WAITKIND_SIGNALLED;
455 status->value.integer = gdb_signal_from_host (WTERMSIG (wstat));
456 lynx_debug ("process terminated with code: %d",
457 status->value.integer);
461 /* Not sure what happened if we get here, or whether we can
462 in fact get here. But if we do, handle the event the best
464 status->kind = TARGET_WAITKIND_STOPPED;
465 status->value.integer = gdb_signal_from_host (0);
466 lynx_debug ("unknown event ????");
469 /* SIGTRAP events are generated for situations other than single-step/
470 breakpoint events (Eg. new-thread events). Handle those other types
471 of events, and resume the execution if necessary. */
472 if (status->kind == TARGET_WAITKIND_STOPPED
473 && status->value.integer == GDB_SIGNAL_TRAP)
475 const int realsig = lynx_ptrace (PTRACE_GETTRACESIG, new_ptid, 0, 0, 0);
477 lynx_debug ("(realsig = %d)", realsig);
481 /* We just added the new thread above. No need to do anything
482 further. Just resume the execution again. */
483 lynx_continue (new_ptid);
487 remove_thread (find_thread_ptid (new_ptid));
488 lynx_continue (new_ptid);
496 /* A wrapper around lynx_wait_1 that also prints debug traces when
497 such debug traces have been activated. */
500 lynx_wait (ptid_t ptid, struct target_waitstatus *status, int options)
504 lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
505 lynx_ptid_get_pid (ptid), lynx_ptid_get_tid (ptid));
506 new_ptid = lynx_wait_1 (ptid, status, options);
507 lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)",
508 lynx_ptid_get_pid (new_ptid), lynx_ptid_get_tid (new_ptid),
513 /* Implement the kill target_ops method. */
518 ptid_t ptid = lynx_ptid_build (pid, 0);
519 struct target_waitstatus status;
520 struct process_info *process;
522 process = find_process_pid (pid);
526 lynx_ptrace (PTRACE_KILL, ptid, 0, 0, 0);
527 lynx_wait (ptid, &status, 0);
528 the_target->mourn (process);
532 /* Implement the detach target_ops method. */
535 lynx_detach (int pid)
537 ptid_t ptid = lynx_ptid_build (pid, 0);
538 struct process_info *process;
540 process = find_process_pid (pid);
544 lynx_ptrace (PTRACE_DETACH, ptid, 0, 0, 0);
545 the_target->mourn (process);
549 /* A callback for find_inferior which removes from the thread list
550 all threads belonging to process PROC. */
553 lynx_delete_thread_callback (struct inferior_list_entry *entry, void *proc)
555 struct process_info *process = (struct process_info *) proc;
557 if (ptid_get_pid (entry->id) == pid_of (process))
559 struct thread_info *thr = find_thread_ptid (entry->id);
567 /* Implement the mourn target_ops method. */
570 lynx_mourn (struct process_info *proc)
572 find_inferior (&all_threads, lynx_delete_thread_callback, proc);
574 /* Free our private data. */
578 remove_process (proc);
581 /* Implement the join target_ops method. */
586 /* The PTRACE_DETACH is sufficient to detach from the process.
587 So no need to do anything extra. */
590 /* Implement the thread_alive target_ops method. */
593 lynx_thread_alive (ptid_t ptid)
595 /* The list of threads is updated at the end of each wait, so it
596 should be up to date. No need to re-fetch it. */
597 return (find_thread_ptid (ptid) != NULL);
600 /* Implement the fetch_registers target_ops method. */
603 lynx_fetch_registers (struct regcache *regcache, int regno)
605 struct lynx_regset_info *regset = lynx_target_regsets;
606 ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
608 lynx_debug ("lynx_fetch_registers (regno = %d)", regno);
610 while (regset->size >= 0)
615 buf = xmalloc (regset->size);
616 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
619 regset->store_function (regcache, buf);
625 /* Implement the store_registers target_ops method. */
628 lynx_store_registers (struct regcache *regcache, int regno)
630 struct lynx_regset_info *regset = lynx_target_regsets;
631 ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
633 lynx_debug ("lynx_store_registers (regno = %d)", regno);
635 while (regset->size >= 0)
640 buf = xmalloc (regset->size);
641 res = lynx_ptrace (regset->get_request, inferior_ptid, (int) buf, 0, 0);
644 /* Then overlay our cached registers on that. */
645 regset->fill_function (regcache, buf);
646 /* Only now do we write the register set. */
647 res = lynx_ptrace (regset->set_request, inferior_ptid, (int) buf,
657 /* Implement the read_memory target_ops method. */
660 lynx_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
662 /* On LynxOS, memory reads needs to be performed in chunks the size
663 of int types, and they should also be aligned accordingly. */
665 const int xfer_size = sizeof (buf);
666 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
667 ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
669 while (addr < memaddr + len)
676 skip = memaddr - addr;
677 if (addr + xfer_size > memaddr + len)
678 truncate = addr + xfer_size - memaddr - len;
679 buf = lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
682 memcpy (myaddr + (addr - memaddr) + skip, (gdb_byte *) &buf + skip,
683 xfer_size - skip - truncate);
690 /* Implement the write_memory target_ops method. */
693 lynx_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
695 /* On LynxOS, memory writes needs to be performed in chunks the size
696 of int types, and they should also be aligned accordingly. */
698 const int xfer_size = sizeof (buf);
699 CORE_ADDR addr = memaddr & -(CORE_ADDR) xfer_size;
700 ptid_t inferior_ptid = thread_to_gdb_id (current_thread);
702 while (addr < memaddr + len)
708 skip = memaddr - addr;
709 if (addr + xfer_size > memaddr + len)
710 truncate = addr + xfer_size - memaddr - len;
711 if (skip > 0 || truncate > 0)
713 /* We need to read the memory at this address in order to preserve
714 the data that we are not overwriting. */
715 lynx_read_memory (addr, (unsigned char *) &buf, xfer_size);
719 memcpy ((gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
720 xfer_size - skip - truncate);
722 lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
731 /* Implement the kill_request target_ops method. */
734 lynx_request_interrupt (void)
736 ptid_t inferior_ptid = thread_to_gdb_id (get_first_thread ());
738 kill (lynx_ptid_get_pid (inferior_ptid), SIGINT);
741 /* The LynxOS target_ops vector. */
743 static struct target_ops lynx_target_ops = {
744 lynx_create_inferior,
745 NULL, /* post_create_inferior */
754 lynx_fetch_registers,
755 lynx_store_registers,
756 NULL, /* prepare_to_access_memory */
757 NULL, /* done_accessing_memory */
760 NULL, /* look_up_symbols */
761 lynx_request_interrupt,
762 NULL, /* read_auxv */
763 NULL, /* supports_z_point_type */
764 NULL, /* insert_point */
765 NULL, /* remove_point */
766 NULL, /* stopped_by_sw_breakpoint */
767 NULL, /* supports_stopped_by_sw_breakpoint */
768 NULL, /* stopped_by_hw_breakpoint */
769 NULL, /* supports_stopped_by_hw_breakpoint */
770 target_can_do_hardware_single_step,
771 NULL, /* stopped_by_watchpoint */
772 NULL, /* stopped_data_address */
773 NULL, /* read_offsets */
774 NULL, /* get_tls_address */
775 NULL, /* qxfer_spu */
776 NULL, /* hostio_last_error */
777 NULL, /* qxfer_osdata */
778 NULL, /* qxfer_siginfo */
779 NULL, /* supports_non_stop */
781 NULL, /* start_non_stop */
782 NULL, /* supports_multi_process */
783 NULL, /* supports_fork_events */
784 NULL, /* supports_vfork_events */
785 NULL, /* supports_exec_events */
786 NULL, /* handle_new_gdb_connection */
787 NULL, /* handle_monitor_command */
791 initialize_low (void)
793 set_target_ops (&lynx_target_ops);
794 the_low_target.arch_setup ();