1 /* Copyright (C) 2009-2019 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>
28 #include "common/gdb_wait.h"
30 #include "common/filestuff.h"
31 #include "common/common-inferior.h"
32 #include "nat/fork-inferior.h"
34 int using_threads
= 1;
36 const struct target_desc
*lynx_tdesc
;
38 /* Per-process private data. */
40 struct process_info_private
42 /* The PTID obtained from the last wait performed on this process.
43 Initialized to null_ptid until the first wait is performed. */
44 ptid_t last_wait_event_ptid
;
47 /* Print a debug trace on standard output if debug_threads is set. */
50 lynx_debug (char *string
, ...)
57 va_start (args
, string
);
58 fprintf (stderr
, "DEBUG(lynx): ");
59 vfprintf (stderr
, string
, args
);
60 fprintf (stderr
, "\n");
64 /* Build a ptid_t given a PID and a LynxOS TID. */
67 lynx_ptid_t (int pid
, long tid
)
69 /* brobecker/2010-06-21: It looks like the LWP field in ptids
70 should be distinct for each thread (see write_ptid where it
71 writes the thread ID from the LWP). So instead of storing
72 the LynxOS tid in the tid field of the ptid, we store it in
74 return ptid_t (pid
, tid
, 0);
77 /* Return the process ID of the given PTID.
79 This function has little reason to exist, it's just a wrapper around
80 ptid_get_pid. But since we have a getter function for the lynxos
81 ptid, it feels cleaner to have a getter for the pid as well. */
84 lynx_ptid_get_pid (ptid_t ptid
)
89 /* Return the LynxOS tid of the given PTID. */
92 lynx_ptid_get_tid (ptid_t ptid
)
94 /* See lynx_ptid_t: The LynxOS tid is stored inside the lwp field
99 /* For a given PTID, return the associated PID as known by the LynxOS
103 lynx_ptrace_pid_from_ptid (ptid_t ptid
)
105 return BUILDPID (lynx_ptid_get_pid (ptid
), lynx_ptid_get_tid (ptid
));
108 /* Return a string image of the ptrace REQUEST number. */
111 ptrace_request_to_str (int request
)
113 #define CASE(X) case X: return #X
116 CASE(PTRACE_TRACEME
);
117 CASE(PTRACE_PEEKTEXT
);
118 CASE(PTRACE_PEEKDATA
);
119 CASE(PTRACE_PEEKUSER
);
120 CASE(PTRACE_POKETEXT
);
121 CASE(PTRACE_POKEDATA
);
122 CASE(PTRACE_POKEUSER
);
125 CASE(PTRACE_SINGLESTEP
);
128 CASE(PTRACE_GETREGS
);
129 CASE(PTRACE_SETREGS
);
130 CASE(PTRACE_GETFPREGS
);
131 CASE(PTRACE_SETFPREGS
);
132 CASE(PTRACE_READDATA
);
133 CASE(PTRACE_WRITEDATA
);
134 CASE(PTRACE_READTEXT
);
135 CASE(PTRACE_WRITETEXT
);
136 CASE(PTRACE_GETFPAREGS
);
137 CASE(PTRACE_SETFPAREGS
);
138 CASE(PTRACE_GETWINDOW
);
139 CASE(PTRACE_SETWINDOW
);
140 CASE(PTRACE_SYSCALL
);
141 CASE(PTRACE_DUMPCORE
);
142 CASE(PTRACE_SETWRBKPT
);
143 CASE(PTRACE_SETACBKPT
);
144 CASE(PTRACE_CLRBKPT
);
145 CASE(PTRACE_GET_UCODE
);
164 #ifdef PTRACE_PEEKUSP
165 CASE(PTRACE_PEEKUSP
);
167 #ifdef PTRACE_POKEUSP
168 CASE(PTRACE_POKEUSP
);
170 CASE(PTRACE_PEEKTHREAD
);
171 CASE(PTRACE_THREADUSER
);
173 CASE(PTRACE_FPWRITE
);
175 CASE(PTRACE_CONT_ONE
);
176 CASE(PTRACE_KILL_ONE
);
177 CASE(PTRACE_SINGLESTEP_ONE
);
178 CASE(PTRACE_GETLOADINFO
);
179 CASE(PTRACE_GETTRACESIG
);
180 #ifdef PTRACE_GETTHREADLIST
181 CASE(PTRACE_GETTHREADLIST
);
186 return "<unknown-request>";
189 /* A wrapper around ptrace that allows us to print debug traces of
190 ptrace calls if debug traces are activated. */
193 lynx_ptrace (int request
, ptid_t ptid
, int addr
, int data
, int addr2
)
196 const int pid
= lynx_ptrace_pid_from_ptid (ptid
);
200 fprintf (stderr
, "PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, "
201 "data=0x%x, addr2=0x%x)",
202 ptrace_request_to_str (request
), pid
, PIDGET (pid
), TIDGET (pid
),
204 result
= ptrace (request
, pid
, addr
, data
, addr2
);
207 fprintf (stderr
, " -> %d (=0x%x)\n", result
, result
);
213 /* Call add_process with the given parameters, and initializes
214 the process' private data. */
216 static struct process_info
*
217 lynx_add_process (int pid
, int attached
)
219 struct process_info
*proc
;
221 proc
= add_process (pid
, attached
);
222 proc
->tdesc
= lynx_tdesc
;
223 proc
->priv
= XCNEW (struct process_info_private
);
224 proc
->priv
->last_wait_event_ptid
= null_ptid
;
229 /* Callback used by fork_inferior to start tracing the inferior. */
236 /* Switch child to its own process group so that signals won't
237 directly affect GDBserver. */
240 trace_start_error_with_name ("pgrp");
241 if (setpgid (0, pgrp
) < 0)
242 trace_start_error_with_name ("setpgid");
243 if (ioctl (0, TIOCSPGRP
, &pgrp
) < 0)
244 trace_start_error_with_name ("ioctl");
245 if (lynx_ptrace (PTRACE_TRACEME
, null_ptid
, 0, 0, 0) < 0)
246 trace_start_error_with_name ("lynx_ptrace");
249 /* Implement the create_inferior method of the target_ops vector. */
252 lynx_create_inferior (const char *program
,
253 const std::vector
<char *> &program_args
)
256 std::string str_program_args
= stringify_argv (program_args
);
258 lynx_debug ("lynx_create_inferior ()");
260 pid
= fork_inferior (program
,
261 str_program_args
.c_str (),
262 get_environ ()->envp (), lynx_ptrace_fun
,
263 NULL
, NULL
, NULL
, NULL
);
265 post_fork_inferior (pid
, program
);
267 lynx_add_process (pid
, 0);
268 /* Do not add the process thread just yet, as we do not know its tid.
269 We will add it later, during the wait for the STOP event corresponding
270 to the lynx_ptrace (PTRACE_TRACEME) call above. */
274 /* Assuming we've just attached to a running inferior whose pid is PID,
275 add all threads running in that process. */
278 lynx_add_threads_after_attach (int pid
)
280 /* Ugh! There appears to be no way to get the list of threads
281 in the program we just attached to. So get the list by calling
282 the "ps" command. This is only needed now, as we will then
283 keep the thread list up to date thanks to thread creation and
284 exit notifications. */
287 int thread_pid
, thread_tid
;
289 f
= popen ("ps atx", "r");
291 perror_with_name ("Cannot get thread list");
293 while (fgets (buf
, sizeof (buf
), f
) != NULL
)
294 if ((sscanf (buf
, "%d %d", &thread_pid
, &thread_tid
) == 2
295 && thread_pid
== pid
))
297 ptid_t thread_ptid
= lynx_ptid_t (pid
, thread_tid
);
299 if (!find_thread_ptid (thread_ptid
))
301 lynx_debug ("New thread: (pid = %d, tid = %d)",
303 add_thread (thread_ptid
, NULL
);
310 /* Implement the attach target_ops method. */
313 lynx_attach (unsigned long pid
)
315 ptid_t ptid
= lynx_ptid_t (pid
, 0);
317 if (lynx_ptrace (PTRACE_ATTACH
, ptid
, 0, 0, 0) != 0)
318 error ("Cannot attach to process %lu: %s (%d)\n", pid
,
319 strerror (errno
), errno
);
321 lynx_add_process (pid
, 1);
322 lynx_add_threads_after_attach (pid
);
327 /* Implement the resume target_ops method. */
330 lynx_resume (struct thread_resume
*resume_info
, size_t n
)
332 ptid_t ptid
= resume_info
[0].thread
;
334 = (resume_info
[0].kind
== resume_step
335 ? (n
== 1 ? PTRACE_SINGLESTEP_ONE
: PTRACE_SINGLESTEP
)
337 const int signal
= resume_info
[0].sig
;
339 /* If given a minus_one_ptid, then try using the current_process'
340 private->last_wait_event_ptid. On most LynxOS versions,
341 using any of the process' thread works well enough, but
342 LynxOS 178 is a little more sensitive, and triggers some
343 unexpected signals (Eg SIG61) when we resume the inferior
344 using a different thread. */
345 if (ptid
== minus_one_ptid
)
346 ptid
= current_process()->priv
->last_wait_event_ptid
;
348 /* The ptid might still be minus_one_ptid; this can happen between
349 the moment we create the inferior or attach to a process, and
350 the moment we resume its execution for the first time. It is
351 fine to use the current_thread's ptid in those cases. */
352 if (ptid
== minus_one_ptid
)
353 ptid
= ptid_of (current_thread
);
355 regcache_invalidate_pid (ptid
.pid ());
358 lynx_ptrace (request
, ptid
, 1, signal
, 0);
360 perror_with_name ("ptrace");
363 /* Resume the execution of the given PTID. */
366 lynx_continue (ptid_t ptid
)
368 struct thread_resume resume_info
;
370 resume_info
.thread
= ptid
;
371 resume_info
.kind
= resume_continue
;
374 lynx_resume (&resume_info
, 1);
377 /* A wrapper around waitpid that handles the various idiosyncrasies
378 of LynxOS' waitpid. */
381 lynx_waitpid (int pid
, int *stat_loc
)
387 ret
= waitpid (pid
, stat_loc
, WNOHANG
);
390 /* An ECHILD error is not indicative of a real problem.
391 It happens for instance while waiting for the inferior
392 to stop after attaching to it. */
394 perror_with_name ("waitpid (WNOHANG)");
398 /* No event with WNOHANG. See if there is one with WUNTRACED. */
399 ret
= waitpid (pid
, stat_loc
, WNOHANG
| WUNTRACED
);
402 /* An ECHILD error is not indicative of a real problem.
403 It happens for instance while waiting for the inferior
404 to stop after attaching to it. */
406 perror_with_name ("waitpid (WNOHANG|WUNTRACED)");
415 /* Implement the wait target_ops method. */
418 lynx_wait_1 (ptid_t ptid
, struct target_waitstatus
*status
, int options
)
425 if (ptid
== minus_one_ptid
)
426 pid
= lynx_ptid_get_pid (ptid_of (current_thread
));
428 pid
= BUILDPID (lynx_ptid_get_pid (ptid
), lynx_ptid_get_tid (ptid
));
432 ret
= lynx_waitpid (pid
, &wstat
);
433 new_ptid
= lynx_ptid_t (ret
, ((union wait
*) &wstat
)->w_tid
);
434 find_process_pid (ret
)->priv
->last_wait_event_ptid
= new_ptid
;
436 /* If this is a new thread, then add it now. The reason why we do
437 this here instead of when handling new-thread events is because
438 we need to add the thread associated to the "main" thread - even
439 for non-threaded applications where the new-thread events are not
441 if (!find_thread_ptid (new_ptid
))
443 lynx_debug ("New thread: (pid = %d, tid = %d)",
444 lynx_ptid_get_pid (new_ptid
), lynx_ptid_get_tid (new_ptid
));
445 add_thread (new_ptid
, NULL
);
448 if (WIFSTOPPED (wstat
))
450 status
->kind
= TARGET_WAITKIND_STOPPED
;
451 status
->value
.integer
= gdb_signal_from_host (WSTOPSIG (wstat
));
452 lynx_debug ("process stopped with signal: %d",
453 status
->value
.integer
);
455 else if (WIFEXITED (wstat
))
457 status
->kind
= TARGET_WAITKIND_EXITED
;
458 status
->value
.integer
= WEXITSTATUS (wstat
);
459 lynx_debug ("process exited with code: %d", status
->value
.integer
);
461 else if (WIFSIGNALED (wstat
))
463 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
464 status
->value
.integer
= gdb_signal_from_host (WTERMSIG (wstat
));
465 lynx_debug ("process terminated with code: %d",
466 status
->value
.integer
);
470 /* Not sure what happened if we get here, or whether we can
471 in fact get here. But if we do, handle the event the best
473 status
->kind
= TARGET_WAITKIND_STOPPED
;
474 status
->value
.integer
= gdb_signal_from_host (0);
475 lynx_debug ("unknown event ????");
478 /* SIGTRAP events are generated for situations other than single-step/
479 breakpoint events (Eg. new-thread events). Handle those other types
480 of events, and resume the execution if necessary. */
481 if (status
->kind
== TARGET_WAITKIND_STOPPED
482 && status
->value
.integer
== GDB_SIGNAL_TRAP
)
484 const int realsig
= lynx_ptrace (PTRACE_GETTRACESIG
, new_ptid
, 0, 0, 0);
486 lynx_debug ("(realsig = %d)", realsig
);
490 /* We just added the new thread above. No need to do anything
491 further. Just resume the execution again. */
492 lynx_continue (new_ptid
);
496 remove_thread (find_thread_ptid (new_ptid
));
497 lynx_continue (new_ptid
);
505 /* A wrapper around lynx_wait_1 that also prints debug traces when
506 such debug traces have been activated. */
509 lynx_wait (ptid_t ptid
, struct target_waitstatus
*status
, int options
)
513 lynx_debug ("lynx_wait (pid = %d, tid = %ld)",
514 lynx_ptid_get_pid (ptid
), lynx_ptid_get_tid (ptid
));
515 new_ptid
= lynx_wait_1 (ptid
, status
, options
);
516 lynx_debug (" -> (pid=%d, tid=%ld, status->kind = %d)",
517 lynx_ptid_get_pid (new_ptid
), lynx_ptid_get_tid (new_ptid
),
522 /* Implement the kill target_ops method. */
525 lynx_kill (process_info
*process
)
527 ptid_t ptid
= lynx_ptid_t (process
->pid
, 0);
528 struct target_waitstatus status
;
530 lynx_ptrace (PTRACE_KILL
, ptid
, 0, 0, 0);
531 lynx_wait (ptid
, &status
, 0);
532 the_target
->mourn (process
);
536 /* Implement the detach target_ops method. */
539 lynx_detach (process_info
*process
)
541 ptid_t ptid
= lynx_ptid_t (process
->pid
, 0);
543 lynx_ptrace (PTRACE_DETACH
, ptid
, 0, 0, 0);
544 the_target
->mourn (process
);
548 /* Implement the mourn target_ops method. */
551 lynx_mourn (struct process_info
*proc
)
553 for_each_thread (proc
->pid
, remove_thread
);
555 /* Free our private data. */
559 remove_process (proc
);
562 /* Implement the join target_ops method. */
567 /* The PTRACE_DETACH is sufficient to detach from the process.
568 So no need to do anything extra. */
571 /* Implement the thread_alive target_ops method. */
574 lynx_thread_alive (ptid_t ptid
)
576 /* The list of threads is updated at the end of each wait, so it
577 should be up to date. No need to re-fetch it. */
578 return (find_thread_ptid (ptid
) != NULL
);
581 /* Implement the fetch_registers target_ops method. */
584 lynx_fetch_registers (struct regcache
*regcache
, int regno
)
586 struct lynx_regset_info
*regset
= lynx_target_regsets
;
587 ptid_t inferior_ptid
= ptid_of (current_thread
);
589 lynx_debug ("lynx_fetch_registers (regno = %d)", regno
);
591 while (regset
->size
>= 0)
596 buf
= xmalloc (regset
->size
);
597 res
= lynx_ptrace (regset
->get_request
, inferior_ptid
, (int) buf
, 0, 0);
600 regset
->store_function (regcache
, buf
);
606 /* Implement the store_registers target_ops method. */
609 lynx_store_registers (struct regcache
*regcache
, int regno
)
611 struct lynx_regset_info
*regset
= lynx_target_regsets
;
612 ptid_t inferior_ptid
= ptid_of (current_thread
);
614 lynx_debug ("lynx_store_registers (regno = %d)", regno
);
616 while (regset
->size
>= 0)
621 buf
= xmalloc (regset
->size
);
622 res
= lynx_ptrace (regset
->get_request
, inferior_ptid
, (int) buf
, 0, 0);
625 /* Then overlay our cached registers on that. */
626 regset
->fill_function (regcache
, buf
);
627 /* Only now do we write the register set. */
628 res
= lynx_ptrace (regset
->set_request
, inferior_ptid
, (int) buf
,
638 /* Implement the read_memory target_ops method. */
641 lynx_read_memory (CORE_ADDR memaddr
, unsigned char *myaddr
, int len
)
643 /* On LynxOS, memory reads needs to be performed in chunks the size
644 of int types, and they should also be aligned accordingly. */
646 const int xfer_size
= sizeof (buf
);
647 CORE_ADDR addr
= memaddr
& -(CORE_ADDR
) xfer_size
;
648 ptid_t inferior_ptid
= ptid_of (current_thread
);
650 while (addr
< memaddr
+ len
)
657 skip
= memaddr
- addr
;
658 if (addr
+ xfer_size
> memaddr
+ len
)
659 truncate
= addr
+ xfer_size
- memaddr
- len
;
660 buf
= lynx_ptrace (PTRACE_PEEKTEXT
, inferior_ptid
, addr
, 0, 0);
663 memcpy (myaddr
+ (addr
- memaddr
) + skip
, (gdb_byte
*) &buf
+ skip
,
664 xfer_size
- skip
- truncate
);
671 /* Implement the write_memory target_ops method. */
674 lynx_write_memory (CORE_ADDR memaddr
, const unsigned char *myaddr
, int len
)
676 /* On LynxOS, memory writes needs to be performed in chunks the size
677 of int types, and they should also be aligned accordingly. */
679 const int xfer_size
= sizeof (buf
);
680 CORE_ADDR addr
= memaddr
& -(CORE_ADDR
) xfer_size
;
681 ptid_t inferior_ptid
= ptid_of (current_thread
);
683 while (addr
< memaddr
+ len
)
689 skip
= memaddr
- addr
;
690 if (addr
+ xfer_size
> memaddr
+ len
)
691 truncate
= addr
+ xfer_size
- memaddr
- len
;
692 if (skip
> 0 || truncate
> 0)
694 /* We need to read the memory at this address in order to preserve
695 the data that we are not overwriting. */
696 lynx_read_memory (addr
, (unsigned char *) &buf
, xfer_size
);
700 memcpy ((gdb_byte
*) &buf
+ skip
, myaddr
+ (addr
- memaddr
) + skip
,
701 xfer_size
- skip
- truncate
);
703 lynx_ptrace (PTRACE_POKETEXT
, inferior_ptid
, addr
, buf
, 0);
712 /* Implement the kill_request target_ops method. */
715 lynx_request_interrupt (void)
717 ptid_t inferior_ptid
= ptid_of (get_first_thread ());
719 kill (lynx_ptid_get_pid (inferior_ptid
), SIGINT
);
722 /* The LynxOS target_ops vector. */
724 static struct target_ops lynx_target_ops
= {
725 lynx_create_inferior
,
726 NULL
, /* post_create_inferior */
735 lynx_fetch_registers
,
736 lynx_store_registers
,
737 NULL
, /* prepare_to_access_memory */
738 NULL
, /* done_accessing_memory */
741 NULL
, /* look_up_symbols */
742 lynx_request_interrupt
,
743 NULL
, /* read_auxv */
744 NULL
, /* supports_z_point_type */
745 NULL
, /* insert_point */
746 NULL
, /* remove_point */
747 NULL
, /* stopped_by_sw_breakpoint */
748 NULL
, /* supports_stopped_by_sw_breakpoint */
749 NULL
, /* stopped_by_hw_breakpoint */
750 NULL
, /* supports_stopped_by_hw_breakpoint */
751 target_can_do_hardware_single_step
,
752 NULL
, /* stopped_by_watchpoint */
753 NULL
, /* stopped_data_address */
754 NULL
, /* read_offsets */
755 NULL
, /* get_tls_address */
756 NULL
, /* qxfer_spu */
757 NULL
, /* hostio_last_error */
758 NULL
, /* qxfer_osdata */
759 NULL
, /* qxfer_siginfo */
760 NULL
, /* supports_non_stop */
762 NULL
, /* start_non_stop */
763 NULL
, /* supports_multi_process */
764 NULL
, /* supports_fork_events */
765 NULL
, /* supports_vfork_events */
766 NULL
, /* supports_exec_events */
767 NULL
, /* handle_new_gdb_connection */
768 NULL
, /* handle_monitor_command */
772 initialize_low (void)
774 set_target_ops (&lynx_target_ops
);
775 the_low_target
.arch_setup ();