23 #include <sys/ptrace.h> 24 #include <sys/piddef.h> 26 #include <sys/ioctl.h> 57 va_start (args,
string);
58 fprintf (stderr,
"DEBUG(lynx): ");
59 vfprintf (stderr,
string, args);
60 fprintf (stderr,
"\n");
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>";
200 fprintf (stderr,
"PTRACE (%s, pid=%d(pid=%d, tid=%d), addr=0x%x, " 201 "data=0x%x, addr2=0x%x)",
204 result =
ptrace (request, pid, addr, data, addr2);
207 fprintf (stderr,
" -> %d (=0x%x)\n", result, result);
241 if (setpgid (0, pgrp) < 0)
243 if (ioctl (0, TIOCSPGRP, &pgrp) < 0)
261 str_program_args.c_str (),
263 NULL, NULL, NULL, NULL);
287 int thread_pid, thread_tid;
289 f = popen (
"ps atx",
"r");
293 while (fgets (buf,
sizeof (buf), f) != NULL)
294 if ((sscanf (buf,
"%d %d", &thread_pid, &thread_tid) == 2
295 && thread_pid ==
pid))
301 lynx_debug (
"New thread: (pid = %d, tid = %d)",
317 if (
lynx_ptrace (PTRACE_ATTACH, ptid, 0, 0, 0) != 0)
318 error (
"Cannot attach to process %lu: %s (%d)\n",
pid,
334 = (resume_info[0].
kind == resume_step
335 ? (n == 1 ? PTRACE_SINGLESTEP_ONE : PTRACE_SINGLESTEP)
337 const int signal = resume_info[0].
sig;
370 resume_info.
thread = ptid;
371 resume_info.
kind = resume_continue;
387 ret = waitpid (pid, stat_loc,
WNOHANG);
443 lynx_debug (
"New thread: (pid = %d, tid = %d)",
450 status->kind = TARGET_WAITKIND_STOPPED;
452 lynx_debug (
"process stopped with signal: %d",
453 status->value.integer);
457 status->kind = TARGET_WAITKIND_EXITED;
459 lynx_debug (
"process exited with code: %d", status->value.integer);
463 status->kind = TARGET_WAITKIND_SIGNALLED;
465 lynx_debug (
"process terminated with code: %d",
466 status->value.integer);
473 status->kind = TARGET_WAITKIND_STOPPED;
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);
513 lynx_debug (
"lynx_wait (pid = %d, tid = %ld)",
516 lynx_debug (
" -> (pid=%d, tid=%ld, status->kind = %d)",
528 struct target_waitstatus status;
599 lynx_debug (
"lynx_fetch_registers (regno = %d)", regno);
601 while (regset->
size >= 0)
624 lynx_debug (
"lynx_store_registers (regno = %d)", regno);
626 while (regset->
size >= 0)
656 const int xfer_size =
sizeof (buf);
660 while (addr < memaddr + len)
667 skip = memaddr - addr;
668 if (addr + xfer_size > memaddr + len)
669 truncate = addr + xfer_size - memaddr - len;
670 buf =
lynx_ptrace (PTRACE_PEEKTEXT, inferior_ptid, addr, 0, 0);
673 memcpy (myaddr + (addr - memaddr) + skip, (
gdb_byte *) &buf + skip,
674 xfer_size - skip - truncate);
689 const int xfer_size =
sizeof (buf);
693 while (addr < memaddr + len)
699 skip = memaddr - addr;
700 if (addr + xfer_size > memaddr + len)
701 truncate = addr + xfer_size - memaddr - len;
702 if (skip > 0 || truncate > 0)
710 memcpy ((
gdb_byte *) &buf + skip, myaddr + (addr - memaddr) + skip,
711 xfer_size - skip - truncate);
713 lynx_ptrace (PTRACE_POKETEXT, inferior_ptid, addr, buf, 0);
struct thread_info * current_thread
int target_can_do_hardware_single_step(void)
struct process_info * add_process(int pid, int attached)
struct thread_info * find_thread_ptid(ptid_t ptid)
void(* store_function)(struct regcache *regcache, const char *buf)
static void lynx_mourn(struct process_info *proc)
int ptid_get_pid(const ptid_t &ptid)
std::string stringify_argv(const std::vector< char *> &args)
static int lynx_ptrace(int request, ptid_t ptid, int addr, int data, int addr2)
static ptid_t ptid_of(const thread_info *thread)
void(* fill_function)(struct regcache *regcache, char *buf)
static int lynx_write_memory(CORE_ADDR memaddr, const unsigned char *myaddr, int len)
void(* mourn)(struct process_info *proc)
struct linux_target_ops the_low_target
static void lynx_ptrace_fun()
static void for_each_thread(Func func)
struct target_ops * the_target
const struct target_desc * tdesc
void perror(const char *)
ptid_t ptid_build(int pid, long lwp, long tid)
static long lynx_ptid_get_tid(ptid_t ptid)
static char * ptrace_request_to_str(int request)
static int lynx_ptrace_pid_from_ptid(ptid_t ptid)
gdb_environ * get_environ()
const struct target_desc * lynx_tdesc
process_info * find_process_pid(int pid)
static void lynx_debug(char *string,...)
static void lynx_resume(struct thread_resume *resume_info, size_t n)
enum gdb_signal gdb_signal_from_host(int)
static int lynx_waitpid(int pid, int *stat_loc)
static int lynx_detach(int pid)
void remove_process(struct process_info *process)
void set_target_ops(struct target_ops *target)
struct process_info * current_process(void)
struct process_info_private * priv
long ptid_get_lwp(const ptid_t &ptid)
void post_fork_inferior(int pid, const char *program)
static int lynx_kill(int pid)
struct thread_info * get_first_thread(void)
static ptid_t lynx_ptid_build(int pid, long tid)
void trace_start_error_with_name(const char *string)
struct lynx_regset_info lynx_target_regsets[]
static int lynx_create_inferior(const char *program, const std::vector< char *> &program_args)
pid_t fork_inferior(const char *exec_file_arg, const std::string &allargs, char **env, void(*traceme_fun)(), void(*init_trace_fun)(int), void(*pre_trace_fun)(), const char *shell_file_arg, void(*exec_fun)(const char *file, char *const *argv, char *const *env))
static ptid_t lynx_wait_1(ptid_t ptid, struct target_waitstatus *status, int options)
ptid_t last_wait_event_ptid
static int lynx_thread_alive(ptid_t ptid)
void perror_with_name(const char *string)
void remove_thread(struct thread_info *thread)
int ptid_equal(const ptid_t &ptid1, const ptid_t &ptid2)
void regcache_invalidate_pid(int pid)
static void lynx_continue(ptid_t ptid)
static ptid_t lynx_wait(ptid_t ptid, struct target_waitstatus *status, int options)
void initialize_low(void)
static struct process_info * lynx_add_process(int pid, int attached)
static int lynx_attach(unsigned long pid)
static void lynx_join(int pid)
static int lynx_ptid_get_pid(ptid_t ptid)
static void lynx_fetch_registers(struct regcache *regcache, int regno)
static std::vector< char * > program_args
struct thread_info * add_thread(ptid_t ptid, void *target_data)
static void lynx_store_registers(struct regcache *regcache, int regno)
static void lynx_add_threads_after_attach(int pid)
void error(const char *fmt,...)
static int lynx_read_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
static void lynx_request_interrupt(void)