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 /* Print a debug trace on standard output if debug_threads is set. */
36 lynx_debug (char *string
, ...)
43 va_start (args
, string
);
44 fprintf (stderr
, "DEBUG(lynx): ");
45 vfprintf (stderr
, string
, args
);
46 fprintf (stderr
, "\n");
50 /* Build a ptid_t given a PID and a LynxOS TID. */
53 lynx_ptid_build (int pid
, long tid
)
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
60 return ptid_build (pid
, tid
, 0);
63 /* Return the process ID of the given PTID.
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. */
70 lynx_ptid_get_pid (ptid_t ptid
)
72 return ptid_get_pid (ptid
);
75 /* Return the LynxOS tid of the given PTID. */
78 lynx_ptid_get_tid (ptid_t ptid
)
80 /* See lynx_ptid_build: The LynxOS tid is stored inside the lwp field
82 return ptid_get_lwp (ptid
);
85 /* For a given PTID, return the associated PID as known by the LynxOS
89 lynx_ptrace_pid_from_ptid (ptid_t ptid
)
91 return BUILDPID (lynx_ptid_get_pid (ptid
), lynx_ptid_get_tid (ptid
));
94 /* Return a string image of the ptrace REQUEST number. */
97 ptrace_request_to_str (int request
)
99 #define CASE(X) case X: return #X
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
);
111 CASE(PTRACE_SINGLESTEP
);
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
);
150 #ifdef PTRACE_PEEKUSP
151 CASE(PTRACE_PEEKUSP
);
153 #ifdef PTRACE_POKEUSP
154 CASE(PTRACE_POKEUSP
);
156 CASE(PTRACE_PEEKTHREAD
);
157 CASE(PTRACE_THREADUSER
);
159 CASE(PTRACE_FPWRITE
);
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
);
172 return "<unknown-request>";
175 /* A wrapper around ptrace that allows us to print debug traces of
176 ptrace calls if debug traces are activated. */
179 lynx_ptrace (int request
, ptid_t ptid
, int addr
, int data
, int addr2
)
182 const int pid
= lynx_ptrace_pid_from_ptid (ptid
);
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
),
190 result
= ptrace (request
, pid
, addr
, data
, addr2
);
193 fprintf (stderr
, " -> %d (=0x%x)\n", result
, result
);
199 /* Implement the create_inferior method of the target_ops vector. */
202 lynx_create_inferior (char *program
, char **allargs
)
206 lynx_debug ("lynx_create_inferior ()");
210 perror_with_name ("fork");
216 /* Switch child to its own process group so that signals won't
217 directly affect gdbserver. */
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
));
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. */
235 /* Implement the attach target_ops method. */
238 lynx_attach (unsigned long pid
)
240 ptid_t ptid
= lynx_ptid_build (pid
, 0);
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
);
246 add_process (pid
, 1);
247 add_thread (ptid
, NULL
);
252 /* Implement the resume target_ops method. */
255 lynx_resume (struct thread_resume
*resume_info
, size_t n
)
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
;
263 if (ptid_equal (ptid
, minus_one_ptid
))
264 ptid
= thread_to_gdb_id (current_inferior
);
266 regcache_invalidate ();
269 lynx_ptrace (request
, ptid
, 1, signal
, 0);
271 perror_with_name ("ptrace");
274 /* Resume the execution of the given PTID. */
277 lynx_continue (ptid_t ptid
)
279 struct thread_resume resume_info
;
281 resume_info
.thread
= ptid
;
282 resume_info
.kind
= resume_continue
;
285 lynx_resume (&resume_info
, 1);
288 /* Remove all inferiors and associated threads. */
291 lynx_clear_inferiors (void)
293 /* We do not use private data, so nothing much to do except calling
298 /* A wrapper around waitpid that handles the various idiosyncrasies
299 of LynxOS' waitpid. */
302 lynx_waitpid (int pid
, int *stat_loc
)
308 ret
= waitpid (pid
, stat_loc
, WNOHANG
);
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. */
315 perror_with_name ("waitpid (WNOHANG)");
319 /* No event with WNOHANG. See if there is one with WUNTRACED. */
320 ret
= waitpid (pid
, stat_loc
, WNOHANG
| WUNTRACED
);
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. */
327 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
336 /* Implement the wait target_ops method. */
339 lynx_wait_1 (ptid_t ptid
, struct target_waitstatus
*status
, int options
)
346 if (ptid_equal (ptid
, minus_one_ptid
))
347 pid
= lynx_ptid_get_pid (thread_to_gdb_id (current_inferior
));
349 pid
= BUILDPID (lynx_ptid_get_pid (ptid
), lynx_ptid_get_tid (ptid
));
353 ret
= lynx_waitpid (pid
, &wstat
);
354 new_ptid
= lynx_ptid_build (ret
, ((union wait
*) &wstat
)->w_tid
);
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
361 if (!find_thread_ptid (new_ptid
))
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
);
368 if (WIFSTOPPED (wstat
))
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
);
375 else if (WIFEXITED (wstat
))
377 status
->kind
= TARGET_WAITKIND_EXITED
;
378 status
->value
.integer
= WEXITSTATUS (wstat
);
379 lynx_debug ("process exited with code: %d", status
->value
.integer
);
381 else if (WIFSIGNALED (wstat
))
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
);
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
393 status
->kind
= TARGET_WAITKIND_STOPPED
;
394 status
->value
.integer
= gdb_signal_from_host (0);
395 lynx_debug ("unknown event ????");
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
)
404 const int realsig
= lynx_ptrace (PTRACE_GETTRACESIG
, new_ptid
, 0, 0, 0);
406 lynx_debug ("(realsig = %d)", realsig
);
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
);
416 remove_thread (find_thread_ptid (new_ptid
));
417 lynx_continue (new_ptid
);
425 /* A wrapper around lynx_wait_1 that also prints debug traces when
426 such debug traces have been activated. */
429 lynx_wait (ptid_t ptid
, struct target_waitstatus
*status
, int options
)
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
),
442 /* Implement the kill target_ops method. */
447 ptid_t ptid
= lynx_ptid_build (pid
, 0);
448 struct target_waitstatus status
;
449 struct process_info
*process
;
451 process
= find_process_pid (pid
);
455 lynx_ptrace (PTRACE_KILL
, ptid
, 0, 0, 0);
456 lynx_wait (ptid
, &status
, 0);
457 the_target
->mourn (process
);
461 /* Implement the detach target_ops method. */
464 lynx_detach (int pid
)
466 ptid_t ptid
= lynx_ptid_build (pid
, 0);
467 struct process_info
*process
;
469 process
= find_process_pid (pid
);
473 lynx_ptrace (PTRACE_DETACH
, ptid
, 0, 0, 0);
474 the_target
->mourn (process
);
478 /* Implement the mourn target_ops method. */
481 lynx_mourn (struct process_info
*proc
)
483 lynx_clear_inferiors ();
486 /* Implement the join target_ops method. */
491 /* The PTRACE_DETACH is sufficient to detach from the process.
492 So no need to do anything extra. */
495 /* Implement the thread_alive target_ops method. */
498 lynx_thread_alive (ptid_t ptid
)
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
);
505 /* Implement the fetch_registers target_ops method. */
508 lynx_fetch_registers (struct regcache
*regcache
, int regno
)
510 struct lynx_regset_info
*regset
= lynx_target_regsets
;
511 ptid_t inferior_ptid
= thread_to_gdb_id (current_inferior
);
513 lynx_debug ("lynx_fetch_registers (regno = %d)", regno
);
515 while (regset
->size
>= 0)
520 buf
= xmalloc (regset
->size
);
521 res
= lynx_ptrace (regset
->get_request
, inferior_ptid
, (int) buf
, 0, 0);
524 regset
->store_function (regcache
, buf
);
530 /* Implement the store_registers target_ops method. */
533 lynx_store_registers (struct regcache
*regcache
, int regno
)
535 struct lynx_regset_info
*regset
= lynx_target_regsets
;
536 ptid_t inferior_ptid
= thread_to_gdb_id (current_inferior
);
538 lynx_debug ("lynx_store_registers (regno = %d)", regno
);
540 while (regset
->size
>= 0)
545 buf
= xmalloc (regset
->size
);
546 res
= lynx_ptrace (regset
->get_request
, inferior_ptid
, (int) buf
, 0, 0);
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
,
562 /* Implement the read_memory target_ops method. */
565 lynx_read_memory (CORE_ADDR memaddr
, unsigned char *myaddr
, int len
)
567 /* On LynxOS, memory reads needs to be performed in chunks the size
568 of int types, and they should also be aligned accordingly. */
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
);
574 while (addr
< memaddr
+ len
)
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);
587 memcpy (myaddr
+ (addr
- memaddr
) + skip
, (gdb_byte
*) &buf
+ skip
,
588 xfer_size
- skip
- truncate
);
595 /* Implement the write_memory target_ops method. */
598 lynx_write_memory (CORE_ADDR memaddr
, const unsigned char *myaddr
, int len
)
600 /* On LynxOS, memory writes needs to be performed in chunks the size
601 of int types, and they should also be aligned accordingly. */
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
);
607 while (addr
< memaddr
+ len
)
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
);
622 memcpy ((gdb_byte
*) &buf
+ skip
, myaddr
+ (addr
- memaddr
) + skip
,
623 xfer_size
- skip
- truncate
);
625 lynx_ptrace (PTRACE_POKETEXT
, inferior_ptid
, addr
, buf
, 0);
634 /* Implement the kill_request target_ops method. */
637 lynx_request_interrupt (void)
639 ptid_t inferior_ptid
= thread_to_gdb_id (current_inferior
);
641 kill (lynx_ptid_get_pid (inferior_ptid
), SIGINT
);
644 /* The LynxOS target_ops vector. */
646 static struct target_ops lynx_target_ops
= {
647 lynx_create_inferior
,
656 lynx_fetch_registers
,
657 lynx_store_registers
,
658 NULL
, /* prepare_to_access_memory */
659 NULL
, /* done_accessing_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 */
677 NULL
, /* start_non_stop */
678 NULL
, /* supports_multi_process */
679 NULL
, /* handle_monitor_command */
683 initialize_low (void)
685 set_target_ops (&lynx_target_ops
);
686 the_low_target
.arch_setup ();