GDB (API)
|
00001 /* Machine independent support for QNX Neutrino /proc (process file system) 00002 for GDB. Written by Colin Burgess at QNX Software Systems Limited. 00003 00004 Copyright (C) 2003-2013 Free Software Foundation, Inc. 00005 00006 Contributed by QNX Software Systems Ltd. 00007 00008 This file is part of GDB. 00009 00010 This program is free software; you can redistribute it and/or modify 00011 it under the terms of the GNU General Public License as published by 00012 the Free Software Foundation; either version 3 of the License, or 00013 (at your option) any later version. 00014 00015 This program is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 GNU General Public License for more details. 00019 00020 You should have received a copy of the GNU General Public License 00021 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00022 00023 #include "defs.h" 00024 00025 #include <fcntl.h> 00026 #include <spawn.h> 00027 #include <sys/debug.h> 00028 #include <sys/procfs.h> 00029 #include <sys/neutrino.h> 00030 #include <sys/syspage.h> 00031 #include "gdb_dirent.h" 00032 #include <sys/netmgr.h> 00033 00034 #include "exceptions.h" 00035 #include "gdb_string.h" 00036 #include "gdbcore.h" 00037 #include "inferior.h" 00038 #include "target.h" 00039 #include "objfiles.h" 00040 #include "gdbthread.h" 00041 #include "nto-tdep.h" 00042 #include "command.h" 00043 #include "regcache.h" 00044 #include "solib.h" 00045 00046 #define NULL_PID 0 00047 #define _DEBUG_FLAG_TRACE (_DEBUG_FLAG_TRACE_EXEC|_DEBUG_FLAG_TRACE_RD|\ 00048 _DEBUG_FLAG_TRACE_WR|_DEBUG_FLAG_TRACE_MODIFY) 00049 00050 static struct target_ops procfs_ops; 00051 00052 int ctl_fd; 00053 00054 static void (*ofunc) (); 00055 00056 static procfs_run run; 00057 00058 static void procfs_open (char *, int); 00059 00060 static int procfs_can_run (void); 00061 00062 static int procfs_xfer_memory (CORE_ADDR, gdb_byte *, int, int, 00063 struct mem_attrib *attrib, 00064 struct target_ops *); 00065 00066 static void init_procfs_ops (void); 00067 00068 static ptid_t do_attach (ptid_t ptid); 00069 00070 static int procfs_can_use_hw_breakpoint (int, int, int); 00071 00072 static int procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type, 00073 struct expression *cond); 00074 00075 static int procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type, 00076 struct expression *cond); 00077 00078 static int procfs_stopped_by_watchpoint (void); 00079 00080 /* These two globals are only ever set in procfs_open(), but are 00081 referenced elsewhere. 'nto_procfs_node' is a flag used to say 00082 whether we are local, or we should get the current node descriptor 00083 for the remote QNX node. */ 00084 static char nto_procfs_path[PATH_MAX] = { "/proc" }; 00085 static unsigned nto_procfs_node = ND_LOCAL_NODE; 00086 00087 /* Return the current QNX Node, or error out. This is a simple 00088 wrapper for the netmgr_strtond() function. The reason this 00089 is required is because QNX node descriptors are transient so 00090 we have to re-acquire them every time. */ 00091 static unsigned 00092 nto_node (void) 00093 { 00094 unsigned node; 00095 00096 if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0) 00097 return ND_LOCAL_NODE; 00098 00099 node = netmgr_strtond (nto_procfs_path, 0); 00100 if (node == -1) 00101 error (_("Lost the QNX node. Debug session probably over.")); 00102 00103 return (node); 00104 } 00105 00106 static enum gdb_osabi 00107 procfs_is_nto_target (bfd *abfd) 00108 { 00109 return GDB_OSABI_QNXNTO; 00110 } 00111 00112 /* This is called when we call 'target procfs <arg>' from the (gdb) prompt. 00113 For QNX6 (nto), the only valid arg will be a QNX node string, 00114 eg: "/net/some_node". If arg is not a valid QNX node, we will 00115 default to local. */ 00116 static void 00117 procfs_open (char *arg, int from_tty) 00118 { 00119 char *nodestr; 00120 char *endstr; 00121 char buffer[50]; 00122 int fd, total_size; 00123 procfs_sysinfo *sysinfo; 00124 struct cleanup *cleanups; 00125 00126 nto_is_nto_target = procfs_is_nto_target; 00127 00128 /* Set the default node used for spawning to this one, 00129 and only override it if there is a valid arg. */ 00130 00131 nto_procfs_node = ND_LOCAL_NODE; 00132 nodestr = arg ? xstrdup (arg) : arg; 00133 00134 init_thread_list (); 00135 00136 if (nodestr) 00137 { 00138 nto_procfs_node = netmgr_strtond (nodestr, &endstr); 00139 if (nto_procfs_node == -1) 00140 { 00141 if (errno == ENOTSUP) 00142 printf_filtered ("QNX Net Manager not found.\n"); 00143 printf_filtered ("Invalid QNX node %s: error %d (%s).\n", nodestr, 00144 errno, safe_strerror (errno)); 00145 xfree (nodestr); 00146 nodestr = NULL; 00147 nto_procfs_node = ND_LOCAL_NODE; 00148 } 00149 else if (*endstr) 00150 { 00151 if (*(endstr - 1) == '/') 00152 *(endstr - 1) = 0; 00153 else 00154 *endstr = 0; 00155 } 00156 } 00157 snprintf (nto_procfs_path, PATH_MAX - 1, "%s%s", nodestr ? nodestr : "", 00158 "/proc"); 00159 if (nodestr) 00160 xfree (nodestr); 00161 00162 fd = open (nto_procfs_path, O_RDONLY); 00163 if (fd == -1) 00164 { 00165 printf_filtered ("Error opening %s : %d (%s)\n", nto_procfs_path, errno, 00166 safe_strerror (errno)); 00167 error (_("Invalid procfs arg")); 00168 } 00169 cleanups = make_cleanup_close (fd); 00170 00171 sysinfo = (void *) buffer; 00172 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, sizeof buffer, 0) != EOK) 00173 { 00174 printf_filtered ("Error getting size: %d (%s)\n", errno, 00175 safe_strerror (errno)); 00176 error (_("Devctl failed.")); 00177 } 00178 else 00179 { 00180 total_size = sysinfo->total_size; 00181 sysinfo = alloca (total_size); 00182 if (!sysinfo) 00183 { 00184 printf_filtered ("Memory error: %d (%s)\n", errno, 00185 safe_strerror (errno)); 00186 error (_("alloca failed.")); 00187 } 00188 else 00189 { 00190 if (devctl (fd, DCMD_PROC_SYSINFO, sysinfo, total_size, 0) != EOK) 00191 { 00192 printf_filtered ("Error getting sysinfo: %d (%s)\n", errno, 00193 safe_strerror (errno)); 00194 error (_("Devctl failed.")); 00195 } 00196 else 00197 { 00198 if (sysinfo->type != 00199 nto_map_arch_to_cputype (gdbarch_bfd_arch_info 00200 (target_gdbarch ())->arch_name)) 00201 error (_("Invalid target CPU.")); 00202 } 00203 } 00204 } 00205 do_cleanups (cleanups); 00206 printf_filtered ("Debugging using %s\n", nto_procfs_path); 00207 } 00208 00209 static void 00210 procfs_set_thread (ptid_t ptid) 00211 { 00212 pid_t tid; 00213 00214 tid = ptid_get_tid (ptid); 00215 devctl (ctl_fd, DCMD_PROC_CURTHREAD, &tid, sizeof (tid), 0); 00216 } 00217 00218 /* Return nonzero if the thread TH is still alive. */ 00219 static int 00220 procfs_thread_alive (struct target_ops *ops, ptid_t ptid) 00221 { 00222 pid_t tid; 00223 pid_t pid; 00224 procfs_status status; 00225 int err; 00226 00227 tid = ptid_get_tid (ptid); 00228 pid = ptid_get_pid (ptid); 00229 00230 if (kill (pid, 0) == -1) 00231 return 0; 00232 00233 status.tid = tid; 00234 if ((err = devctl (ctl_fd, DCMD_PROC_TIDSTATUS, 00235 &status, sizeof (status), 0)) != EOK) 00236 return 0; 00237 00238 /* Thread is alive or dead but not yet joined, 00239 or dead and there is an alive (or dead unjoined) thread with 00240 higher tid. 00241 00242 If the tid is not the same as requested, requested tid is dead. */ 00243 return (status.tid == tid) && (status.state != STATE_DEAD); 00244 } 00245 00246 static void 00247 update_thread_private_data_name (struct thread_info *new_thread, 00248 const char *newname) 00249 { 00250 int newnamelen; 00251 struct private_thread_info *pti; 00252 00253 gdb_assert (newname != NULL); 00254 gdb_assert (new_thread != NULL); 00255 newnamelen = strlen (newname); 00256 if (!new_thread->private) 00257 { 00258 new_thread->private = xmalloc (offsetof (struct private_thread_info, 00259 name) 00260 + newnamelen + 1); 00261 memcpy (new_thread->private->name, newname, newnamelen + 1); 00262 } 00263 else if (strcmp (newname, new_thread->private->name) != 0) 00264 { 00265 /* Reallocate if neccessary. */ 00266 int oldnamelen = strlen (new_thread->private->name); 00267 00268 if (oldnamelen < newnamelen) 00269 new_thread->private = xrealloc (new_thread->private, 00270 offsetof (struct private_thread_info, 00271 name) 00272 + newnamelen + 1); 00273 memcpy (new_thread->private->name, newname, newnamelen + 1); 00274 } 00275 } 00276 00277 static void 00278 update_thread_private_data (struct thread_info *new_thread, 00279 pthread_t tid, int state, int flags) 00280 { 00281 struct private_thread_info *pti; 00282 procfs_info pidinfo; 00283 struct _thread_name *tn; 00284 procfs_threadctl tctl; 00285 00286 #if _NTO_VERSION > 630 00287 gdb_assert (new_thread != NULL); 00288 00289 if (devctl (ctl_fd, DCMD_PROC_INFO, &pidinfo, 00290 sizeof(pidinfo), 0) != EOK) 00291 return; 00292 00293 memset (&tctl, 0, sizeof (tctl)); 00294 tctl.cmd = _NTO_TCTL_NAME; 00295 tn = (struct _thread_name *) (&tctl.data); 00296 00297 /* Fetch name for the given thread. */ 00298 tctl.tid = tid; 00299 tn->name_buf_len = sizeof (tctl.data) - sizeof (*tn); 00300 tn->new_name_len = -1; /* Getting, not setting. */ 00301 if (devctl (ctl_fd, DCMD_PROC_THREADCTL, &tctl, sizeof (tctl), NULL) != EOK) 00302 tn->name_buf[0] = '\0'; 00303 00304 tn->name_buf[_NTO_THREAD_NAME_MAX] = '\0'; 00305 00306 update_thread_private_data_name (new_thread, tn->name_buf); 00307 00308 pti = (struct private_thread_info *) new_thread->private; 00309 pti->tid = tid; 00310 pti->state = state; 00311 pti->flags = flags; 00312 #endif /* _NTO_VERSION */ 00313 } 00314 00315 static void 00316 procfs_find_new_threads (struct target_ops *ops) 00317 { 00318 procfs_status status; 00319 pid_t pid; 00320 ptid_t ptid; 00321 pthread_t tid; 00322 struct thread_info *new_thread; 00323 00324 if (ctl_fd == -1) 00325 return; 00326 00327 pid = ptid_get_pid (inferior_ptid); 00328 00329 status.tid = 1; 00330 00331 for (tid = 1;; ++tid) 00332 { 00333 if (status.tid == tid 00334 && (devctl (ctl_fd, DCMD_PROC_TIDSTATUS, &status, sizeof (status), 0) 00335 != EOK)) 00336 break; 00337 if (status.tid != tid) 00338 /* The reason why this would not be equal is that devctl might have 00339 returned different tid, meaning the requested tid no longer exists 00340 (e.g. thread exited). */ 00341 continue; 00342 ptid = ptid_build (pid, 0, tid); 00343 new_thread = find_thread_ptid (ptid); 00344 if (!new_thread) 00345 new_thread = add_thread (ptid); 00346 update_thread_private_data (new_thread, tid, status.state, 0); 00347 status.tid++; 00348 } 00349 return; 00350 } 00351 00352 static void 00353 do_closedir_cleanup (void *dir) 00354 { 00355 closedir (dir); 00356 } 00357 00358 void 00359 procfs_pidlist (char *args, int from_tty) 00360 { 00361 DIR *dp = NULL; 00362 struct dirent *dirp = NULL; 00363 char buf[512]; 00364 procfs_info *pidinfo = NULL; 00365 procfs_debuginfo *info = NULL; 00366 procfs_status *status = NULL; 00367 pid_t num_threads = 0; 00368 pid_t pid; 00369 char name[512]; 00370 struct cleanup *cleanups; 00371 00372 dp = opendir (nto_procfs_path); 00373 if (dp == NULL) 00374 { 00375 fprintf_unfiltered (gdb_stderr, "failed to opendir \"%s\" - %d (%s)", 00376 nto_procfs_path, errno, safe_strerror (errno)); 00377 return; 00378 } 00379 00380 cleanups = make_cleanup (do_closedir_cleanup, dp); 00381 00382 /* Start scan at first pid. */ 00383 rewinddir (dp); 00384 00385 do 00386 { 00387 int fd; 00388 struct cleanup *inner_cleanup; 00389 00390 /* Get the right pid and procfs path for the pid. */ 00391 do 00392 { 00393 dirp = readdir (dp); 00394 if (dirp == NULL) 00395 { 00396 do_cleanups (cleanups); 00397 return; 00398 } 00399 snprintf (buf, 511, "%s/%s/as", nto_procfs_path, dirp->d_name); 00400 pid = atoi (dirp->d_name); 00401 } 00402 while (pid == 0); 00403 00404 /* Open the procfs path. */ 00405 fd = open (buf, O_RDONLY); 00406 if (fd == -1) 00407 { 00408 fprintf_unfiltered (gdb_stderr, "failed to open %s - %d (%s)\n", 00409 buf, errno, safe_strerror (errno)); 00410 do_cleanups (cleanups); 00411 return; 00412 } 00413 inner_cleanup = make_cleanup_close (fd); 00414 00415 pidinfo = (procfs_info *) buf; 00416 if (devctl (fd, DCMD_PROC_INFO, pidinfo, sizeof (buf), 0) != EOK) 00417 { 00418 fprintf_unfiltered (gdb_stderr, 00419 "devctl DCMD_PROC_INFO failed - %d (%s)\n", 00420 errno, safe_strerror (errno)); 00421 break; 00422 } 00423 num_threads = pidinfo->num_threads; 00424 00425 info = (procfs_debuginfo *) buf; 00426 if (devctl (fd, DCMD_PROC_MAPDEBUG_BASE, info, sizeof (buf), 0) != EOK) 00427 strcpy (name, "unavailable"); 00428 else 00429 strcpy (name, info->path); 00430 00431 /* Collect state info on all the threads. */ 00432 status = (procfs_status *) buf; 00433 for (status->tid = 1; status->tid <= num_threads; status->tid++) 00434 { 00435 if (devctl (fd, DCMD_PROC_TIDSTATUS, status, sizeof (buf), 0) != EOK 00436 && status->tid != 0) 00437 break; 00438 if (status->tid != 0) 00439 printf_filtered ("%s - %d/%d\n", name, pid, status->tid); 00440 } 00441 00442 do_cleanups (inner_cleanup); 00443 } 00444 while (dirp != NULL); 00445 00446 do_cleanups (cleanups); 00447 return; 00448 } 00449 00450 void 00451 procfs_meminfo (char *args, int from_tty) 00452 { 00453 procfs_mapinfo *mapinfos = NULL; 00454 static int num_mapinfos = 0; 00455 procfs_mapinfo *mapinfo_p, *mapinfo_p2; 00456 int flags = ~0, err, num, i, j; 00457 00458 struct 00459 { 00460 procfs_debuginfo info; 00461 char buff[_POSIX_PATH_MAX]; 00462 } map; 00463 00464 struct info 00465 { 00466 unsigned addr; 00467 unsigned size; 00468 unsigned flags; 00469 unsigned debug_vaddr; 00470 unsigned long long offset; 00471 }; 00472 00473 struct printinfo 00474 { 00475 unsigned long long ino; 00476 unsigned dev; 00477 struct info text; 00478 struct info data; 00479 char name[256]; 00480 } printme; 00481 00482 /* Get the number of map entrys. */ 00483 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, NULL, 0, &num); 00484 if (err != EOK) 00485 { 00486 printf ("failed devctl num mapinfos - %d (%s)\n", err, 00487 safe_strerror (err)); 00488 return; 00489 } 00490 00491 mapinfos = xmalloc (num * sizeof (procfs_mapinfo)); 00492 00493 num_mapinfos = num; 00494 mapinfo_p = mapinfos; 00495 00496 /* Fill the map entrys. */ 00497 err = devctl (ctl_fd, DCMD_PROC_MAPINFO, mapinfo_p, num 00498 * sizeof (procfs_mapinfo), &num); 00499 if (err != EOK) 00500 { 00501 printf ("failed devctl mapinfos - %d (%s)\n", err, safe_strerror (err)); 00502 xfree (mapinfos); 00503 return; 00504 } 00505 00506 num = min (num, num_mapinfos); 00507 00508 /* Run through the list of mapinfos, and store the data and text info 00509 so we can print it at the bottom of the loop. */ 00510 for (mapinfo_p = mapinfos, i = 0; i < num; i++, mapinfo_p++) 00511 { 00512 if (!(mapinfo_p->flags & flags)) 00513 mapinfo_p->ino = 0; 00514 00515 if (mapinfo_p->ino == 0) /* Already visited. */ 00516 continue; 00517 00518 map.info.vaddr = mapinfo_p->vaddr; 00519 00520 err = devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); 00521 if (err != EOK) 00522 continue; 00523 00524 memset (&printme, 0, sizeof printme); 00525 printme.dev = mapinfo_p->dev; 00526 printme.ino = mapinfo_p->ino; 00527 printme.text.addr = mapinfo_p->vaddr; 00528 printme.text.size = mapinfo_p->size; 00529 printme.text.flags = mapinfo_p->flags; 00530 printme.text.offset = mapinfo_p->offset; 00531 printme.text.debug_vaddr = map.info.vaddr; 00532 strcpy (printme.name, map.info.path); 00533 00534 /* Check for matching data. */ 00535 for (mapinfo_p2 = mapinfos, j = 0; j < num; j++, mapinfo_p2++) 00536 { 00537 if (mapinfo_p2->vaddr != mapinfo_p->vaddr 00538 && mapinfo_p2->ino == mapinfo_p->ino 00539 && mapinfo_p2->dev == mapinfo_p->dev) 00540 { 00541 map.info.vaddr = mapinfo_p2->vaddr; 00542 err = 00543 devctl (ctl_fd, DCMD_PROC_MAPDEBUG, &map, sizeof (map), 0); 00544 if (err != EOK) 00545 continue; 00546 00547 if (strcmp (map.info.path, printme.name)) 00548 continue; 00549 00550 /* Lower debug_vaddr is always text, if nessessary, swap. */ 00551 if ((int) map.info.vaddr < (int) printme.text.debug_vaddr) 00552 { 00553 memcpy (&(printme.data), &(printme.text), 00554 sizeof (printme.data)); 00555 printme.text.addr = mapinfo_p2->vaddr; 00556 printme.text.size = mapinfo_p2->size; 00557 printme.text.flags = mapinfo_p2->flags; 00558 printme.text.offset = mapinfo_p2->offset; 00559 printme.text.debug_vaddr = map.info.vaddr; 00560 } 00561 else 00562 { 00563 printme.data.addr = mapinfo_p2->vaddr; 00564 printme.data.size = mapinfo_p2->size; 00565 printme.data.flags = mapinfo_p2->flags; 00566 printme.data.offset = mapinfo_p2->offset; 00567 printme.data.debug_vaddr = map.info.vaddr; 00568 } 00569 mapinfo_p2->ino = 0; 00570 } 00571 } 00572 mapinfo_p->ino = 0; 00573 00574 printf_filtered ("%s\n", printme.name); 00575 printf_filtered ("\ttext=%08x bytes @ 0x%08x\n", printme.text.size, 00576 printme.text.addr); 00577 printf_filtered ("\t\tflags=%08x\n", printme.text.flags); 00578 printf_filtered ("\t\tdebug=%08x\n", printme.text.debug_vaddr); 00579 printf_filtered ("\t\toffset=%s\n", phex (printme.text.offset, 8)); 00580 if (printme.data.size) 00581 { 00582 printf_filtered ("\tdata=%08x bytes @ 0x%08x\n", printme.data.size, 00583 printme.data.addr); 00584 printf_filtered ("\t\tflags=%08x\n", printme.data.flags); 00585 printf_filtered ("\t\tdebug=%08x\n", printme.data.debug_vaddr); 00586 printf_filtered ("\t\toffset=%s\n", phex (printme.data.offset, 8)); 00587 } 00588 printf_filtered ("\tdev=0x%x\n", printme.dev); 00589 printf_filtered ("\tino=0x%x\n", (unsigned int) printme.ino); 00590 } 00591 xfree (mapinfos); 00592 return; 00593 } 00594 00595 /* Print status information about what we're accessing. */ 00596 static void 00597 procfs_files_info (struct target_ops *ignore) 00598 { 00599 struct inferior *inf = current_inferior (); 00600 00601 printf_unfiltered ("\tUsing the running image of %s %s via %s.\n", 00602 inf->attach_flag ? "attached" : "child", 00603 target_pid_to_str (inferior_ptid), nto_procfs_path); 00604 } 00605 00606 /* Mark our target-struct as eligible for stray "run" and "attach" 00607 commands. */ 00608 static int 00609 procfs_can_run (void) 00610 { 00611 return 1; 00612 } 00613 00614 /* Attach to process PID, then initialize for debugging it. */ 00615 static void 00616 procfs_attach (struct target_ops *ops, char *args, int from_tty) 00617 { 00618 char *exec_file; 00619 int pid; 00620 struct inferior *inf; 00621 00622 pid = parse_pid_to_attach (args); 00623 00624 if (pid == getpid ()) 00625 error (_("Attaching GDB to itself is not a good idea...")); 00626 00627 if (from_tty) 00628 { 00629 exec_file = (char *) get_exec_file (0); 00630 00631 if (exec_file) 00632 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file, 00633 target_pid_to_str (pid_to_ptid (pid))); 00634 else 00635 printf_unfiltered ("Attaching to %s\n", 00636 target_pid_to_str (pid_to_ptid (pid))); 00637 00638 gdb_flush (gdb_stdout); 00639 } 00640 inferior_ptid = do_attach (pid_to_ptid (pid)); 00641 inf = current_inferior (); 00642 inferior_appeared (inf, pid); 00643 inf->attach_flag = 1; 00644 00645 push_target (ops); 00646 00647 procfs_find_new_threads (ops); 00648 } 00649 00650 static void 00651 procfs_post_attach (pid_t pid) 00652 { 00653 if (exec_bfd) 00654 solib_create_inferior_hook (0); 00655 } 00656 00657 static ptid_t 00658 do_attach (ptid_t ptid) 00659 { 00660 procfs_status status; 00661 struct sigevent event; 00662 char path[PATH_MAX]; 00663 00664 snprintf (path, PATH_MAX - 1, "%s/%d/as", nto_procfs_path, 00665 ptid_get_pid (ptid)); 00666 ctl_fd = open (path, O_RDWR); 00667 if (ctl_fd == -1) 00668 error (_("Couldn't open proc file %s, error %d (%s)"), path, errno, 00669 safe_strerror (errno)); 00670 if (devctl (ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) != EOK) 00671 error (_("Couldn't stop process")); 00672 00673 /* Define a sigevent for process stopped notification. */ 00674 event.sigev_notify = SIGEV_SIGNAL_THREAD; 00675 event.sigev_signo = SIGUSR1; 00676 event.sigev_code = 0; 00677 event.sigev_value.sival_ptr = NULL; 00678 event.sigev_priority = -1; 00679 devctl (ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); 00680 00681 if (devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0) == EOK 00682 && status.flags & _DEBUG_FLAG_STOPPED) 00683 SignalKill (nto_node (), ptid_get_pid (ptid), 0, SIGCONT, 0, 0); 00684 nto_init_solib_absolute_prefix (); 00685 return ptid_build (ptid_get_pid (ptid), 0, status.tid); 00686 } 00687 00688 /* Ask the user what to do when an interrupt is received. */ 00689 static void 00690 interrupt_query (void) 00691 { 00692 target_terminal_ours (); 00693 00694 if (query (_("Interrupted while waiting for the program.\n\ 00695 Give up (and stop debugging it)? "))) 00696 { 00697 target_mourn_inferior (); 00698 quit (); 00699 } 00700 00701 target_terminal_inferior (); 00702 } 00703 00704 /* The user typed ^C twice. */ 00705 static void 00706 nto_interrupt_twice (int signo) 00707 { 00708 signal (signo, ofunc); 00709 interrupt_query (); 00710 signal (signo, nto_interrupt_twice); 00711 } 00712 00713 static void 00714 nto_interrupt (int signo) 00715 { 00716 /* If this doesn't work, try more severe steps. */ 00717 signal (signo, nto_interrupt_twice); 00718 00719 target_stop (inferior_ptid); 00720 } 00721 00722 static ptid_t 00723 procfs_wait (struct target_ops *ops, 00724 ptid_t ptid, struct target_waitstatus *ourstatus, int options) 00725 { 00726 sigset_t set; 00727 siginfo_t info; 00728 procfs_status status; 00729 static int exit_signo = 0; /* To track signals that cause termination. */ 00730 00731 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 00732 00733 if (ptid_equal (inferior_ptid, null_ptid)) 00734 { 00735 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00736 ourstatus->value.sig = GDB_SIGNAL_0; 00737 exit_signo = 0; 00738 return null_ptid; 00739 } 00740 00741 sigemptyset (&set); 00742 sigaddset (&set, SIGUSR1); 00743 00744 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); 00745 while (!(status.flags & _DEBUG_FLAG_ISTOP)) 00746 { 00747 ofunc = (void (*)()) signal (SIGINT, nto_interrupt); 00748 sigwaitinfo (&set, &info); 00749 signal (SIGINT, ofunc); 00750 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); 00751 } 00752 00753 if (status.flags & _DEBUG_FLAG_SSTEP) 00754 { 00755 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00756 ourstatus->value.sig = GDB_SIGNAL_TRAP; 00757 } 00758 /* Was it a breakpoint? */ 00759 else if (status.flags & _DEBUG_FLAG_TRACE) 00760 { 00761 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00762 ourstatus->value.sig = GDB_SIGNAL_TRAP; 00763 } 00764 else if (status.flags & _DEBUG_FLAG_ISTOP) 00765 { 00766 switch (status.why) 00767 { 00768 case _DEBUG_WHY_SIGNALLED: 00769 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00770 ourstatus->value.sig = 00771 gdb_signal_from_host (status.info.si_signo); 00772 exit_signo = 0; 00773 break; 00774 case _DEBUG_WHY_FAULTED: 00775 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00776 if (status.info.si_signo == SIGTRAP) 00777 { 00778 ourstatus->value.sig = 0; 00779 exit_signo = 0; 00780 } 00781 else 00782 { 00783 ourstatus->value.sig = 00784 gdb_signal_from_host (status.info.si_signo); 00785 exit_signo = ourstatus->value.sig; 00786 } 00787 break; 00788 00789 case _DEBUG_WHY_TERMINATED: 00790 { 00791 int waitval = 0; 00792 00793 waitpid (ptid_get_pid (inferior_ptid), &waitval, WNOHANG); 00794 if (exit_signo) 00795 { 00796 /* Abnormal death. */ 00797 ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 00798 ourstatus->value.sig = exit_signo; 00799 } 00800 else 00801 { 00802 /* Normal death. */ 00803 ourstatus->kind = TARGET_WAITKIND_EXITED; 00804 ourstatus->value.integer = WEXITSTATUS (waitval); 00805 } 00806 exit_signo = 0; 00807 break; 00808 } 00809 00810 case _DEBUG_WHY_REQUESTED: 00811 /* We are assuming a requested stop is due to a SIGINT. */ 00812 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00813 ourstatus->value.sig = GDB_SIGNAL_INT; 00814 exit_signo = 0; 00815 break; 00816 } 00817 } 00818 00819 return ptid_build (status.pid, 0, status.tid); 00820 } 00821 00822 /* Read the current values of the inferior's registers, both the 00823 general register set and floating point registers (if supported) 00824 and update gdb's idea of their current values. */ 00825 static void 00826 procfs_fetch_registers (struct target_ops *ops, 00827 struct regcache *regcache, int regno) 00828 { 00829 union 00830 { 00831 procfs_greg greg; 00832 procfs_fpreg fpreg; 00833 procfs_altreg altreg; 00834 } 00835 reg; 00836 int regsize; 00837 00838 procfs_set_thread (inferior_ptid); 00839 if (devctl (ctl_fd, DCMD_PROC_GETGREG, ®, sizeof (reg), ®size) == EOK) 00840 nto_supply_gregset (regcache, (char *) ®.greg); 00841 if (devctl (ctl_fd, DCMD_PROC_GETFPREG, ®, sizeof (reg), ®size) 00842 == EOK) 00843 nto_supply_fpregset (regcache, (char *) ®.fpreg); 00844 if (devctl (ctl_fd, DCMD_PROC_GETALTREG, ®, sizeof (reg), ®size) 00845 == EOK) 00846 nto_supply_altregset (regcache, (char *) ®.altreg); 00847 } 00848 00849 /* Copy LEN bytes to/from inferior's memory starting at MEMADDR 00850 from/to debugger memory starting at MYADDR. Copy from inferior 00851 if DOWRITE is zero or to inferior if DOWRITE is nonzero. 00852 00853 Returns the length copied, which is either the LEN argument or 00854 zero. This xfer function does not do partial moves, since procfs_ops 00855 doesn't allow memory operations to cross below us in the target stack 00856 anyway. */ 00857 static int 00858 procfs_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int dowrite, 00859 struct mem_attrib *attrib, struct target_ops *target) 00860 { 00861 int nbytes = 0; 00862 00863 if (lseek (ctl_fd, (off_t) memaddr, SEEK_SET) == (off_t) memaddr) 00864 { 00865 if (dowrite) 00866 nbytes = write (ctl_fd, myaddr, len); 00867 else 00868 nbytes = read (ctl_fd, myaddr, len); 00869 if (nbytes < 0) 00870 nbytes = 0; 00871 } 00872 return (nbytes); 00873 } 00874 00875 /* Take a program previously attached to and detaches it. 00876 The program resumes execution and will no longer stop 00877 on signals, etc. We'd better not have left any breakpoints 00878 in the program or it'll die when it hits one. */ 00879 static void 00880 procfs_detach (struct target_ops *ops, char *args, int from_tty) 00881 { 00882 int siggnal = 0; 00883 int pid; 00884 00885 if (from_tty) 00886 { 00887 char *exec_file = get_exec_file (0); 00888 if (exec_file == 0) 00889 exec_file = ""; 00890 printf_unfiltered ("Detaching from program: %s %s\n", 00891 exec_file, target_pid_to_str (inferior_ptid)); 00892 gdb_flush (gdb_stdout); 00893 } 00894 if (args) 00895 siggnal = atoi (args); 00896 00897 if (siggnal) 00898 SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, siggnal, 0, 0); 00899 00900 close (ctl_fd); 00901 ctl_fd = -1; 00902 00903 pid = ptid_get_pid (inferior_ptid); 00904 inferior_ptid = null_ptid; 00905 detach_inferior (pid); 00906 init_thread_list (); 00907 unpush_target (&procfs_ops); /* Pop out of handling an inferior. */ 00908 } 00909 00910 static int 00911 procfs_breakpoint (CORE_ADDR addr, int type, int size) 00912 { 00913 procfs_break brk; 00914 00915 brk.type = type; 00916 brk.addr = addr; 00917 brk.size = size; 00918 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); 00919 if (errno != EOK) 00920 return 1; 00921 return 0; 00922 } 00923 00924 static int 00925 procfs_insert_breakpoint (struct gdbarch *gdbarch, 00926 struct bp_target_info *bp_tgt) 00927 { 00928 return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, 0); 00929 } 00930 00931 static int 00932 procfs_remove_breakpoint (struct gdbarch *gdbarch, 00933 struct bp_target_info *bp_tgt) 00934 { 00935 return procfs_breakpoint (bp_tgt->placed_address, _DEBUG_BREAK_EXEC, -1); 00936 } 00937 00938 static int 00939 procfs_insert_hw_breakpoint (struct gdbarch *gdbarch, 00940 struct bp_target_info *bp_tgt) 00941 { 00942 return procfs_breakpoint (bp_tgt->placed_address, 00943 _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, 0); 00944 } 00945 00946 static int 00947 procfs_remove_hw_breakpoint (struct gdbarch *gdbarch, 00948 struct bp_target_info *bp_tgt) 00949 { 00950 return procfs_breakpoint (bp_tgt->placed_address, 00951 _DEBUG_BREAK_EXEC | _DEBUG_BREAK_HW, -1); 00952 } 00953 00954 static void 00955 procfs_resume (struct target_ops *ops, 00956 ptid_t ptid, int step, enum gdb_signal signo) 00957 { 00958 int signal_to_pass; 00959 procfs_status status; 00960 sigset_t *run_fault = (sigset_t *) (void *) &run.fault; 00961 00962 if (ptid_equal (inferior_ptid, null_ptid)) 00963 return; 00964 00965 procfs_set_thread (ptid_equal (ptid, minus_one_ptid) ? inferior_ptid : 00966 ptid); 00967 00968 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; 00969 if (step) 00970 run.flags |= _DEBUG_RUN_STEP; 00971 00972 sigemptyset (run_fault); 00973 sigaddset (run_fault, FLTBPT); 00974 sigaddset (run_fault, FLTTRACE); 00975 sigaddset (run_fault, FLTILL); 00976 sigaddset (run_fault, FLTPRIV); 00977 sigaddset (run_fault, FLTBOUNDS); 00978 sigaddset (run_fault, FLTIOVF); 00979 sigaddset (run_fault, FLTIZDIV); 00980 sigaddset (run_fault, FLTFPE); 00981 /* Peter V will be changing this at some point. */ 00982 sigaddset (run_fault, FLTPAGE); 00983 00984 run.flags |= _DEBUG_RUN_ARM; 00985 00986 signal_to_pass = gdb_signal_to_host (signo); 00987 00988 if (signal_to_pass) 00989 { 00990 devctl (ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); 00991 signal_to_pass = gdb_signal_to_host (signo); 00992 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) 00993 { 00994 if (signal_to_pass != status.info.si_signo) 00995 { 00996 SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, 00997 signal_to_pass, 0, 0); 00998 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; 00999 } 01000 else /* Let it kill the program without telling us. */ 01001 sigdelset (&run.trace, signal_to_pass); 01002 } 01003 } 01004 else 01005 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; 01006 01007 errno = devctl (ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); 01008 if (errno != EOK) 01009 { 01010 perror (_("run error!\n")); 01011 return; 01012 } 01013 } 01014 01015 static void 01016 procfs_mourn_inferior (struct target_ops *ops) 01017 { 01018 if (!ptid_equal (inferior_ptid, null_ptid)) 01019 { 01020 SignalKill (nto_node (), ptid_get_pid (inferior_ptid), 0, SIGKILL, 0, 0); 01021 close (ctl_fd); 01022 } 01023 inferior_ptid = null_ptid; 01024 init_thread_list (); 01025 unpush_target (&procfs_ops); 01026 generic_mourn_inferior (); 01027 } 01028 01029 /* This function breaks up an argument string into an argument 01030 vector suitable for passing to execvp(). 01031 E.g., on "run a b c d" this routine would get as input 01032 the string "a b c d", and as output it would fill in argv with 01033 the four arguments "a", "b", "c", "d". The only additional 01034 functionality is simple quoting. The gdb command: 01035 run a "b c d" f 01036 will fill in argv with the three args "a", "b c d", "e". */ 01037 static void 01038 breakup_args (char *scratch, char **argv) 01039 { 01040 char *pp, *cp = scratch; 01041 char quoting = 0; 01042 01043 for (;;) 01044 { 01045 /* Scan past leading separators. */ 01046 quoting = 0; 01047 while (*cp == ' ' || *cp == '\t' || *cp == '\n') 01048 cp++; 01049 01050 /* Break if at end of string. */ 01051 if (*cp == '\0') 01052 break; 01053 01054 /* Take an arg. */ 01055 if (*cp == '"') 01056 { 01057 cp++; 01058 quoting = strchr (cp, '"') ? 1 : 0; 01059 } 01060 01061 *argv++ = cp; 01062 01063 /* Scan for next arg separator. */ 01064 pp = cp; 01065 if (quoting) 01066 cp = strchr (pp, '"'); 01067 if ((cp == NULL) || (!quoting)) 01068 cp = strchr (pp, ' '); 01069 if (cp == NULL) 01070 cp = strchr (pp, '\t'); 01071 if (cp == NULL) 01072 cp = strchr (pp, '\n'); 01073 01074 /* No separators => end of string => break. */ 01075 if (cp == NULL) 01076 { 01077 pp = cp; 01078 break; 01079 } 01080 01081 /* Replace the separator with a terminator. */ 01082 *cp++ = '\0'; 01083 } 01084 01085 /* Execv requires a null-terminated arg vector. */ 01086 *argv = NULL; 01087 } 01088 01089 static void 01090 procfs_create_inferior (struct target_ops *ops, char *exec_file, 01091 char *allargs, char **env, int from_tty) 01092 { 01093 struct inheritance inherit; 01094 pid_t pid; 01095 int flags, errn; 01096 char **argv, *args; 01097 const char *in = "", *out = "", *err = ""; 01098 int fd, fds[3]; 01099 sigset_t set; 01100 const char *inferior_io_terminal = get_inferior_io_terminal (); 01101 struct inferior *inf; 01102 01103 argv = xmalloc (((strlen (allargs) + 1) / (unsigned) 2 + 2) * 01104 sizeof (*argv)); 01105 argv[0] = get_exec_file (1); 01106 if (!argv[0]) 01107 { 01108 if (exec_file) 01109 argv[0] = exec_file; 01110 else 01111 return; 01112 } 01113 01114 args = xstrdup (allargs); 01115 breakup_args (args, exec_file ? &argv[1] : &argv[0]); 01116 01117 argv = nto_parse_redirection (argv, &in, &out, &err); 01118 01119 fds[0] = STDIN_FILENO; 01120 fds[1] = STDOUT_FILENO; 01121 fds[2] = STDERR_FILENO; 01122 01123 /* If the user specified I/O via gdb's --tty= arg, use it, but only 01124 if the i/o is not also being specified via redirection. */ 01125 if (inferior_io_terminal) 01126 { 01127 if (!in[0]) 01128 in = inferior_io_terminal; 01129 if (!out[0]) 01130 out = inferior_io_terminal; 01131 if (!err[0]) 01132 err = inferior_io_terminal; 01133 } 01134 01135 if (in[0]) 01136 { 01137 fd = open (in, O_RDONLY); 01138 if (fd == -1) 01139 perror (in); 01140 else 01141 fds[0] = fd; 01142 } 01143 if (out[0]) 01144 { 01145 fd = open (out, O_WRONLY); 01146 if (fd == -1) 01147 perror (out); 01148 else 01149 fds[1] = fd; 01150 } 01151 if (err[0]) 01152 { 01153 fd = open (err, O_WRONLY); 01154 if (fd == -1) 01155 perror (err); 01156 else 01157 fds[2] = fd; 01158 } 01159 01160 /* Clear any pending SIGUSR1's but keep the behavior the same. */ 01161 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); 01162 01163 sigemptyset (&set); 01164 sigaddset (&set, SIGUSR1); 01165 sigprocmask (SIG_UNBLOCK, &set, NULL); 01166 01167 memset (&inherit, 0, sizeof (inherit)); 01168 01169 if (ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) != 0) 01170 { 01171 inherit.nd = nto_node (); 01172 inherit.flags |= SPAWN_SETND; 01173 inherit.flags &= ~SPAWN_EXEC; 01174 } 01175 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; 01176 inherit.pgroup = SPAWN_NEWPGROUP; 01177 pid = spawnp (argv[0], 3, fds, &inherit, argv, 01178 ND_NODE_CMP (nto_procfs_node, ND_LOCAL_NODE) == 0 ? env : 0); 01179 xfree (args); 01180 01181 sigprocmask (SIG_BLOCK, &set, NULL); 01182 01183 if (pid == -1) 01184 error (_("Error spawning %s: %d (%s)"), argv[0], errno, 01185 safe_strerror (errno)); 01186 01187 if (fds[0] != STDIN_FILENO) 01188 close (fds[0]); 01189 if (fds[1] != STDOUT_FILENO) 01190 close (fds[1]); 01191 if (fds[2] != STDERR_FILENO) 01192 close (fds[2]); 01193 01194 inferior_ptid = do_attach (pid_to_ptid (pid)); 01195 procfs_find_new_threads (ops); 01196 01197 inf = current_inferior (); 01198 inferior_appeared (inf, pid); 01199 inf->attach_flag = 0; 01200 01201 flags = _DEBUG_FLAG_KLC; /* Kill-on-Last-Close flag. */ 01202 errn = devctl (ctl_fd, DCMD_PROC_SET_FLAG, &flags, sizeof (flags), 0); 01203 if (errn != EOK) 01204 { 01205 /* FIXME: expected warning? */ 01206 /* warning( "Failed to set Kill-on-Last-Close flag: errno = %d(%s)\n", 01207 errn, strerror(errn) ); */ 01208 } 01209 push_target (ops); 01210 target_terminal_init (); 01211 01212 if (exec_bfd != NULL 01213 || (symfile_objfile != NULL && symfile_objfile->obfd != NULL)) 01214 solib_create_inferior_hook (0); 01215 } 01216 01217 static void 01218 procfs_stop (ptid_t ptid) 01219 { 01220 devctl (ctl_fd, DCMD_PROC_STOP, NULL, 0, 0); 01221 } 01222 01223 static void 01224 procfs_kill_inferior (struct target_ops *ops) 01225 { 01226 target_mourn_inferior (); 01227 } 01228 01229 /* Store register REGNO, or all registers if REGNO == -1, from the contents 01230 of REGISTERS. */ 01231 static void 01232 procfs_prepare_to_store (struct regcache *regcache) 01233 { 01234 } 01235 01236 /* Fill buf with regset and return devctl cmd to do the setting. Return 01237 -1 if we fail to get the regset. Store size of regset in regsize. */ 01238 static int 01239 get_regset (int regset, char *buf, int bufsize, int *regsize) 01240 { 01241 int dev_get, dev_set; 01242 switch (regset) 01243 { 01244 case NTO_REG_GENERAL: 01245 dev_get = DCMD_PROC_GETGREG; 01246 dev_set = DCMD_PROC_SETGREG; 01247 break; 01248 01249 case NTO_REG_FLOAT: 01250 dev_get = DCMD_PROC_GETFPREG; 01251 dev_set = DCMD_PROC_SETFPREG; 01252 break; 01253 01254 case NTO_REG_ALT: 01255 dev_get = DCMD_PROC_GETALTREG; 01256 dev_set = DCMD_PROC_SETALTREG; 01257 break; 01258 01259 case NTO_REG_SYSTEM: 01260 default: 01261 return -1; 01262 } 01263 if (devctl (ctl_fd, dev_get, buf, bufsize, regsize) != EOK) 01264 return -1; 01265 01266 return dev_set; 01267 } 01268 01269 void 01270 procfs_store_registers (struct target_ops *ops, 01271 struct regcache *regcache, int regno) 01272 { 01273 union 01274 { 01275 procfs_greg greg; 01276 procfs_fpreg fpreg; 01277 procfs_altreg altreg; 01278 } 01279 reg; 01280 unsigned off; 01281 int len, regset, regsize, dev_set, err; 01282 char *data; 01283 01284 if (ptid_equal (inferior_ptid, null_ptid)) 01285 return; 01286 procfs_set_thread (inferior_ptid); 01287 01288 if (regno == -1) 01289 { 01290 for (regset = NTO_REG_GENERAL; regset < NTO_REG_END; regset++) 01291 { 01292 dev_set = get_regset (regset, (char *) ®, 01293 sizeof (reg), ®size); 01294 if (dev_set == -1) 01295 continue; 01296 01297 if (nto_regset_fill (regcache, regset, (char *) ®) == -1) 01298 continue; 01299 01300 err = devctl (ctl_fd, dev_set, ®, regsize, 0); 01301 if (err != EOK) 01302 fprintf_unfiltered (gdb_stderr, 01303 "Warning unable to write regset %d: %s\n", 01304 regno, safe_strerror (err)); 01305 } 01306 } 01307 else 01308 { 01309 regset = nto_regset_id (regno); 01310 if (regset == -1) 01311 return; 01312 01313 dev_set = get_regset (regset, (char *) ®, sizeof (reg), ®size); 01314 if (dev_set == -1) 01315 return; 01316 01317 len = nto_register_area (get_regcache_arch (regcache), 01318 regno, regset, &off); 01319 01320 if (len < 1) 01321 return; 01322 01323 regcache_raw_collect (regcache, regno, (char *) ® + off); 01324 01325 err = devctl (ctl_fd, dev_set, ®, regsize, 0); 01326 if (err != EOK) 01327 fprintf_unfiltered (gdb_stderr, 01328 "Warning unable to write regset %d: %s\n", regno, 01329 safe_strerror (err)); 01330 } 01331 } 01332 01333 /* Set list of signals to be handled in the target. */ 01334 01335 static void 01336 procfs_pass_signals (int numsigs, unsigned char *pass_signals) 01337 { 01338 int signo; 01339 01340 sigfillset (&run.trace); 01341 01342 for (signo = 1; signo < NSIG; signo++) 01343 { 01344 int target_signo = gdb_signal_from_host (signo); 01345 if (target_signo < numsigs && pass_signals[target_signo]) 01346 sigdelset (&run.trace, signo); 01347 } 01348 } 01349 01350 static struct tidinfo * 01351 procfs_thread_info (pid_t pid, short tid) 01352 { 01353 /* NYI */ 01354 return NULL; 01355 } 01356 01357 static char * 01358 procfs_pid_to_str (struct target_ops *ops, ptid_t ptid) 01359 { 01360 static char buf[1024]; 01361 int pid, tid, n; 01362 struct tidinfo *tip; 01363 01364 pid = ptid_get_pid (ptid); 01365 tid = ptid_get_tid (ptid); 01366 01367 n = snprintf (buf, 1023, "process %d", pid); 01368 01369 #if 0 /* NYI */ 01370 tip = procfs_thread_info (pid, tid); 01371 if (tip != NULL) 01372 snprintf (&buf[n], 1023, " (state = 0x%02x)", tip->state); 01373 #endif 01374 01375 return buf; 01376 } 01377 01378 static void 01379 init_procfs_ops (void) 01380 { 01381 procfs_ops.to_shortname = "procfs"; 01382 procfs_ops.to_longname = "QNX Neutrino procfs child process"; 01383 procfs_ops.to_doc = 01384 "QNX Neutrino procfs child process (started by the \"run\" command).\n\ 01385 target procfs <node>"; 01386 procfs_ops.to_open = procfs_open; 01387 procfs_ops.to_attach = procfs_attach; 01388 procfs_ops.to_post_attach = procfs_post_attach; 01389 procfs_ops.to_detach = procfs_detach; 01390 procfs_ops.to_resume = procfs_resume; 01391 procfs_ops.to_wait = procfs_wait; 01392 procfs_ops.to_fetch_registers = procfs_fetch_registers; 01393 procfs_ops.to_store_registers = procfs_store_registers; 01394 procfs_ops.to_prepare_to_store = procfs_prepare_to_store; 01395 procfs_ops.deprecated_xfer_memory = procfs_xfer_memory; 01396 procfs_ops.to_files_info = procfs_files_info; 01397 procfs_ops.to_insert_breakpoint = procfs_insert_breakpoint; 01398 procfs_ops.to_remove_breakpoint = procfs_remove_breakpoint; 01399 procfs_ops.to_can_use_hw_breakpoint = procfs_can_use_hw_breakpoint; 01400 procfs_ops.to_insert_hw_breakpoint = procfs_insert_hw_breakpoint; 01401 procfs_ops.to_remove_hw_breakpoint = procfs_remove_breakpoint; 01402 procfs_ops.to_insert_watchpoint = procfs_insert_hw_watchpoint; 01403 procfs_ops.to_remove_watchpoint = procfs_remove_hw_watchpoint; 01404 procfs_ops.to_stopped_by_watchpoint = procfs_stopped_by_watchpoint; 01405 procfs_ops.to_terminal_init = terminal_init_inferior; 01406 procfs_ops.to_terminal_inferior = terminal_inferior; 01407 procfs_ops.to_terminal_ours_for_output = terminal_ours_for_output; 01408 procfs_ops.to_terminal_ours = terminal_ours; 01409 procfs_ops.to_terminal_info = child_terminal_info; 01410 procfs_ops.to_kill = procfs_kill_inferior; 01411 procfs_ops.to_create_inferior = procfs_create_inferior; 01412 procfs_ops.to_mourn_inferior = procfs_mourn_inferior; 01413 procfs_ops.to_can_run = procfs_can_run; 01414 procfs_ops.to_pass_signals = procfs_pass_signals; 01415 procfs_ops.to_thread_alive = procfs_thread_alive; 01416 procfs_ops.to_find_new_threads = procfs_find_new_threads; 01417 procfs_ops.to_pid_to_str = procfs_pid_to_str; 01418 procfs_ops.to_stop = procfs_stop; 01419 procfs_ops.to_stratum = process_stratum; 01420 procfs_ops.to_has_all_memory = default_child_has_all_memory; 01421 procfs_ops.to_has_memory = default_child_has_memory; 01422 procfs_ops.to_has_stack = default_child_has_stack; 01423 procfs_ops.to_has_registers = default_child_has_registers; 01424 procfs_ops.to_has_execution = default_child_has_execution; 01425 procfs_ops.to_magic = OPS_MAGIC; 01426 procfs_ops.to_have_continuable_watchpoint = 1; 01427 procfs_ops.to_extra_thread_info = nto_extra_thread_info; 01428 } 01429 01430 #define OSTYPE_NTO 1 01431 01432 void 01433 _initialize_procfs (void) 01434 { 01435 sigset_t set; 01436 01437 init_procfs_ops (); 01438 add_target (&procfs_ops); 01439 01440 /* We use SIGUSR1 to gain control after we block waiting for a process. 01441 We use sigwaitevent to wait. */ 01442 sigemptyset (&set); 01443 sigaddset (&set, SIGUSR1); 01444 sigprocmask (SIG_BLOCK, &set, NULL); 01445 01446 /* Initially, make sure all signals are reported. */ 01447 sigfillset (&run.trace); 01448 01449 /* Stuff some information. */ 01450 nto_cpuinfo_flags = SYSPAGE_ENTRY (cpuinfo)->flags; 01451 nto_cpuinfo_valid = 1; 01452 01453 add_info ("pidlist", procfs_pidlist, _("pidlist")); 01454 add_info ("meminfo", procfs_meminfo, _("memory information")); 01455 01456 nto_is_nto_target = procfs_is_nto_target; 01457 } 01458 01459 01460 static int 01461 procfs_hw_watchpoint (int addr, int len, int type) 01462 { 01463 procfs_break brk; 01464 01465 switch (type) 01466 { 01467 case 1: /* Read. */ 01468 brk.type = _DEBUG_BREAK_RD; 01469 break; 01470 case 2: /* Read/Write. */ 01471 brk.type = _DEBUG_BREAK_RW; 01472 break; 01473 default: /* Modify. */ 01474 /* FIXME: brk.type = _DEBUG_BREAK_RWM gives EINVAL for some reason. */ 01475 brk.type = _DEBUG_BREAK_RW; 01476 } 01477 brk.type |= _DEBUG_BREAK_HW; /* Always ask for HW. */ 01478 brk.addr = addr; 01479 brk.size = len; 01480 01481 errno = devctl (ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0); 01482 if (errno != EOK) 01483 { 01484 perror (_("Failed to set hardware watchpoint")); 01485 return -1; 01486 } 01487 return 0; 01488 } 01489 01490 static int 01491 procfs_can_use_hw_breakpoint (int type, int cnt, int othertype) 01492 { 01493 return 1; 01494 } 01495 01496 static int 01497 procfs_remove_hw_watchpoint (CORE_ADDR addr, int len, int type, 01498 struct expression *cond) 01499 { 01500 return procfs_hw_watchpoint (addr, -1, type); 01501 } 01502 01503 static int 01504 procfs_insert_hw_watchpoint (CORE_ADDR addr, int len, int type, 01505 struct expression *cond) 01506 { 01507 return procfs_hw_watchpoint (addr, len, type); 01508 } 01509 01510 static int 01511 procfs_stopped_by_watchpoint (void) 01512 { 01513 return 0; 01514 }