29 #include <sys/procfs.h>
31 #include <sys/iomgr.h>
32 #include <sys/neutrino.h>
47 fprintf (stderr,
"nto:");
48 va_start (arg_list, fmt);
49 vfprintf (stderr, fmt, arg_list);
53 #define TRACE nto_trace
71 memset (nto_inferior, 0,
sizeof (
struct nto_inferior));
73 nto_inferior->
pid = -1;
106 TRACE (
"%s: Error: failed to set current thread\n", __func__);
122 TRACE (
"%s pid:%d\n", __func__, nto_inferior->
pid);
124 if (nto_inferior->
ctl_fd == -1)
127 for (tid = 1;; ++tid)
129 procfs_status status;
134 err = devctl (nto_inferior->
ctl_fd, DCMD_PROC_TIDSTATUS, &status,
137 if (err != EOK || status.tid == 0)
141 while (tid != status.tid || status.state == STATE_DEAD)
149 TRACE (
"Removing thread %d\n", tid);
152 if (tid == status.tid)
157 if (status.state != STATE_DEAD)
159 TRACE (
"Adding thread %d\n", tid);
172 procfs_status status;
173 struct sigevent event;
196 event.sigev_notify = SIGEV_SIGNAL_THREAD;
197 event.sigev_signo = SIGUSR1;
198 event.sigev_code = 0;
199 event.sigev_value.sival_ptr = NULL;
200 event.sigev_priority = -1;
205 && (status.flags & _DEBUG_FLAG_STOPPED))
211 ptid =
ptid_build (status.pid, status.tid, 0);
215 TRACE (
"Adding thread: pid=%d tid=%ld\n", status.pid,
250 TRACE (
"Error in %s : errno=%d (%s)\n", __func__, e,
strerror (e));
282 unsigned char *myaddr,
287 unsigned int len_read = 0;
305 sizeof (anint), 0) !=
sizeof (anint))
309 data_ofs += (anint + 2) *
sizeof (
void *);
315 (
unsigned char *)&anint,
sizeof (anint), 0)
318 data_ofs +=
sizeof (anint);
322 initial_stack += data_ofs;
324 memset (myaddr, 0, len);
325 while (len_read <= len -
sizeof (auxv_t))
327 auxv_t *auxv = (auxv_t *)myaddr;
332 sizeof (auxv_t), 0) ==
sizeof (auxv_t))
334 if (auxv->a_type != AT_NULL)
337 len_read +=
sizeof (auxv_t);
339 if (auxv->a_type == AT_PHNUM)
341 initial_stack +=
sizeof (auxv_t);
346 TRACE (
"auxv: len_read: %d\n", len_read);
355 struct inheritance inherit;
359 TRACE (
"%s %s\n", __func__, program);
361 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN));
364 sigaddset (&set, SIGUSR1);
365 sigprocmask (SIG_UNBLOCK, &set, NULL);
367 memset (&inherit, 0,
sizeof (inherit));
368 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD;
369 inherit.pgroup = SPAWN_NEWPGROUP;
370 pid = spawnp (program, 0, NULL, &inherit, allargs, 0);
371 sigprocmask (SIG_BLOCK, &set, NULL);
387 TRACE (
"%s %ld\n", __func__, pid);
389 error (
"Unable to attach to %ld\n", pid);
398 TRACE (
"%s %d\n", __func__, pid);
409 TRACE (
"%s %d\n", __func__, pid);
436 TRACE (
"%s: %s\n", __func__, res ?
"yes" :
"no");
446 procfs_status status;
450 TRACE (
"%s\n", __func__);
452 sigset_t *run_fault = (sigset_t *) (
void *) &run.fault;
456 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE;
457 if (resume_info->
kind == resume_step)
458 run.flags |= _DEBUG_RUN_STEP;
459 run.flags |= _DEBUG_RUN_ARM;
461 sigemptyset (run_fault);
462 sigaddset (run_fault, FLTBPT);
463 sigaddset (run_fault, FLTTRACE);
464 sigaddset (run_fault, FLTILL);
465 sigaddset (run_fault, FLTPRIV);
466 sigaddset (run_fault, FLTBOUNDS);
467 sigaddset (run_fault, FLTIOVF);
468 sigaddset (run_fault, FLTIZDIV);
469 sigaddset (run_fault, FLTFPE);
470 sigaddset (run_fault, FLTPAGE);
471 sigaddset (run_fault, FLTSTACK);
472 sigaddset (run_fault, FLTACCESS);
474 sigemptyset (&run.trace);
475 if (resume_info->
sig)
481 signal_to_pass = resume_info->
sig;
482 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED))
484 if (signal_to_pass != status.info.si_signo)
486 kill (status.pid, signal_to_pass);
487 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG;
490 sigdelset (&run.trace, signal_to_pass);
494 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT;
496 sigfillset (&run.trace);
511 struct target_waitstatus *ourstatus,
int target_options)
515 procfs_status status;
516 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD
517 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY);
519 TRACE (
"%s\n", __func__);
521 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
524 sigaddset (&set, SIGUSR1);
527 while (!(status.flags & _DEBUG_FLAG_ISTOP))
529 sigwaitinfo (&set, &info);
535 if (status.flags & _DEBUG_FLAG_SSTEP)
538 ourstatus->kind = TARGET_WAITKIND_STOPPED;
539 ourstatus->value.sig = GDB_SIGNAL_TRAP;
542 else if (status.flags & trace_mask)
545 ourstatus->kind = TARGET_WAITKIND_STOPPED;
546 ourstatus->value.sig = GDB_SIGNAL_TRAP;
548 else if (status.flags & _DEBUG_FLAG_ISTOP)
553 case _DEBUG_WHY_SIGNALLED:
554 TRACE (
" SIGNALLED\n");
555 ourstatus->kind = TARGET_WAITKIND_STOPPED;
556 ourstatus->value.sig =
560 case _DEBUG_WHY_FAULTED:
561 TRACE (
" FAULTED\n");
562 ourstatus->kind = TARGET_WAITKIND_STOPPED;
563 if (status.info.si_signo == SIGTRAP)
565 ourstatus->value.sig = 0;
570 ourstatus->value.sig =
576 case _DEBUG_WHY_TERMINATED:
580 TRACE (
" TERMINATED\n");
585 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
591 ourstatus->kind = TARGET_WAITKIND_EXITED;
598 case _DEBUG_WHY_REQUESTED:
599 TRACE (
"REQUESTED\n");
601 ourstatus->kind = TARGET_WAITKIND_STOPPED;
602 ourstatus->value.sig = GDB_SIGNAL_INT;
608 return ptid_build (status.pid, status.tid, 0);
621 TRACE (
"%s (regno=%d)\n", __func__, regno);
627 TRACE (
"current_thread is NULL\n");
641 const unsigned int registeroffset
644 ((
char *)&greg) + registeroffset);
649 const unsigned int registeroffset
651 if (registeroffset == -1)
657 TRACE (
"ERROR reading registers from inferior.\n");
670 TRACE (
"%s (regno:%d)\n", __func__, regno);
674 TRACE (
"current_thread is NULL\n");
681 memset (&greg, 0,
sizeof (greg));
684 const unsigned int regoffset
691 TRACE (
"Error: setting registers.\n");
702 TRACE (
"%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len);
706 TRACE (
"Failed to read memory\n");
723 TRACE (
"%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len);
724 if ((len_written =
nto_xfer_memory (memaddr, (
unsigned char *)myaddr, len,
728 TRACE (
"Wanted to write: %d but written: %d\n", len, len_written);
740 TRACE (
"%s\n", __func__);
743 TRACE (
"Error stopping inferior.\n");
757 procfs_info procinfo;
759 TRACE (
"%s\n", __func__);
768 initial_stack = procinfo.initial_stack;
795 int wtype = _DEBUG_BREAK_HW;
797 TRACE (
"%s type:%c addr: 0x%08lx len:%d\n", __func__, (
int)type, addr, len);
801 wtype = _DEBUG_BREAK_EXEC;
804 wtype |= _DEBUG_BREAK_EXEC;
807 wtype |= _DEBUG_BREAK_RW;
810 wtype |= _DEBUG_BREAK_RD;
813 wtype |= _DEBUG_BREAK_RW;
827 int wtype = _DEBUG_BREAK_HW;
829 TRACE (
"%s type:%c addr: 0x%08lx len:%d\n", __func__, (
int)type, addr, len);
833 wtype = _DEBUG_BREAK_EXEC;
836 wtype |= _DEBUG_BREAK_EXEC;
839 wtype |= _DEBUG_BREAK_RW;
842 wtype |= _DEBUG_BREAK_RD;
845 wtype |= _DEBUG_BREAK_RW;
863 TRACE (
"%s\n", __func__);
871 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR
872 | _DEBUG_FLAG_TRACE_MODIFY;
873 procfs_status status;
878 if (err == EOK && (status.flags & watchmask))
882 TRACE (
"%s: %s\n", __func__, ret ?
"yes" :
"no");
895 TRACE (
"%s\n", __func__);
904 procfs_status status;
907 sizeof (status), 0) == EOK)
911 TRACE (
"%s: 0x%08lx\n", __func__, ret);
920 TRACE (
"%s\n", __func__);
978 TRACE (
"%s\n", __func__);
986 sigaddset (&set, SIGUSR1);
987 sigprocmask (SIG_BLOCK, &set, NULL);
struct thread_info * current_thread
void collect_register(struct regcache *regcache, int n, void *buf)
struct process_info * add_process(int pid, int attached)
struct thread_info * find_thread_ptid(ptid_t ptid)
static int nto_detach(int pid)
static int nto_read_auxv(CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
static int nto_breakpoint(CORE_ADDR addr, int type, int size)
static int nto_write_memory(CORE_ADDR memaddr, const unsigned char *myaddr, int len)
int ptid_equal(ptid_t ptid1, ptid_t ptid2)
static void do_detach(void)
static int nto_attach(unsigned long pid)
static void nto_resume(struct thread_resume *resume_info, size_t n)
static CORE_ADDR nto_stopped_data_address(void)
static void nto_trace(const char *fmt,...)
static void nto_mourn(struct process_info *process)
void set_breakpoint_data(const unsigned char *bp_data, int bp_len)
static void nto_find_new_threads(struct nto_inferior *nto_inferior)
struct linux_target_ops the_low_target
static pid_t do_attach(pid_t pid)
static int nto_insert_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
const struct target_desc * tdesc
const unsigned char * breakpoint
static int nto_remove_point(enum raw_bkpt_type type, CORE_ADDR addr, int size, struct raw_breakpoint *bp)
static int nto_read_memory(CORE_ADDR memaddr, unsigned char *myaddr, int len)
ptid_t ptid_build(int pid, long lwp, long tid)
static ptid_t nto_wait(ptid_t ptid, struct target_waitstatus *ourstatus, int target_options)
void regcache_invalidate(void)
static int nto_thread_alive(ptid_t ptid)
static int nto_read_auxv_from_initial_stack(CORE_ADDR initial_stack, unsigned char *myaddr, unsigned int len)
static void nto_request_interrupt(void)
ptid_t thread_to_gdb_id(struct thread_info *thread)
enum gdb_signal gdb_signal_from_host(int)
void remove_process(struct process_info *process)
void set_target_ops(struct target_ops *target)
static int nto_stopped_by_watchpoint(void)
char nto_procfs_path[PATH_MAX]
static int nto_create_inferior(char *program, char **allargs)
int ptid_get_pid(ptid_t ptid)
static void nto_store_registers(struct regcache *regcache, int regno)
static int nto_supports_non_stop(void)
void initialize_low(void)
int xsnprintf(char *str, size_t size, const char *format,...)
static int nto_kill(int pid)
void hostio_last_error_from_errno(char *buf)
static int nto_xfer_memory(off_t memaddr, unsigned char *myaddr, int len, int dowrite)
#define Z_PACKET_ACCESS_WP
static void init_nto_inferior(struct nto_inferior *nto_inferior)
void remove_thread(struct thread_info *thread)
long ptid_get_lwp(ptid_t ptid)
static void nto_fetch_registers(struct regcache *regcache, int regno)
void supply_register(struct regcache *regcache, int n, const void *buf)
struct thread_info * add_thread(ptid_t ptid, void *target_data)
void error(const char *fmt,...)
static int nto_supports_z_point_type(char z_type)
const struct target_desc * nto_tdesc
#define Z_PACKET_WRITE_WP
static int nto_set_thread(ptid_t ptid)