GDBserver
|
00001 /* QNX Neutrino specific low level interface, for the remote server 00002 for GDB. 00003 Copyright (C) 2009-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 00021 #include "server.h" 00022 #include "gdbthread.h" 00023 #include "nto-low.h" 00024 #include "hostio.h" 00025 00026 #include <limits.h> 00027 #include <fcntl.h> 00028 #include <spawn.h> 00029 #include <sys/procfs.h> 00030 #include <sys/auxv.h> 00031 #include <stdarg.h> 00032 #include <sys/iomgr.h> 00033 #include <sys/neutrino.h> 00034 00035 00036 extern int using_threads; 00037 int using_threads = 1; 00038 00039 const struct target_desc *nto_tdesc; 00040 00041 static void 00042 nto_trace (const char *fmt, ...) 00043 { 00044 va_list arg_list; 00045 00046 if (debug_threads == 0) 00047 return; 00048 fprintf (stderr, "nto:"); 00049 va_start (arg_list, fmt); 00050 vfprintf (stderr, fmt, arg_list); 00051 va_end (arg_list); 00052 } 00053 00054 #define TRACE nto_trace 00055 00056 /* Structure holding neutrino specific information about 00057 inferior. */ 00058 00059 struct nto_inferior 00060 { 00061 char nto_procfs_path[PATH_MAX]; 00062 int ctl_fd; 00063 pid_t pid; 00064 int exit_signo; /* For tracking exit status. */ 00065 }; 00066 00067 static struct nto_inferior nto_inferior; 00068 00069 static void 00070 init_nto_inferior (struct nto_inferior *nto_inferior) 00071 { 00072 memset (nto_inferior, 0, sizeof (struct nto_inferior)); 00073 nto_inferior->ctl_fd = -1; 00074 nto_inferior->pid = -1; 00075 } 00076 00077 static void 00078 do_detach (void) 00079 { 00080 if (nto_inferior.ctl_fd != -1) 00081 { 00082 nto_trace ("Closing fd\n"); 00083 close (nto_inferior.ctl_fd); 00084 init_nto_inferior (&nto_inferior); 00085 } 00086 } 00087 00088 /* Set current thread. Return 1 on success, 0 otherwise. */ 00089 00090 static int 00091 nto_set_thread (ptid_t ptid) 00092 { 00093 int res = 0; 00094 00095 TRACE ("%s pid: %d tid: %ld\n", __func__, ptid_get_pid (ptid), 00096 ptid_get_lwp (ptid)); 00097 if (nto_inferior.ctl_fd != -1 00098 && !ptid_equal (ptid, null_ptid) 00099 && !ptid_equal (ptid, minus_one_ptid)) 00100 { 00101 pthread_t tid = ptid_get_lwp (ptid); 00102 00103 if (EOK == devctl (nto_inferior.ctl_fd, DCMD_PROC_CURTHREAD, &tid, 00104 sizeof (tid), 0)) 00105 res = 1; 00106 else 00107 TRACE ("%s: Error: failed to set current thread\n", __func__); 00108 } 00109 return res; 00110 } 00111 00112 /* This function will determine all alive threads. Note that we do not list 00113 dead but unjoined threads even though they are still in the process' thread 00114 list. 00115 00116 NTO_INFERIOR must not be NULL. */ 00117 00118 static void 00119 nto_find_new_threads (struct nto_inferior *nto_inferior) 00120 { 00121 pthread_t tid; 00122 00123 TRACE ("%s pid:%d\n", __func__, nto_inferior->pid); 00124 00125 if (nto_inferior->ctl_fd == -1) 00126 return; 00127 00128 for (tid = 1;; ++tid) 00129 { 00130 procfs_status status; 00131 ptid_t ptid; 00132 int err; 00133 00134 status.tid = tid; 00135 err = devctl (nto_inferior->ctl_fd, DCMD_PROC_TIDSTATUS, &status, 00136 sizeof (status), 0); 00137 00138 if (err != EOK || status.tid == 0) 00139 break; 00140 00141 /* All threads in between are gone. */ 00142 while (tid != status.tid || status.state == STATE_DEAD) 00143 { 00144 struct thread_info *ti; 00145 00146 ptid = ptid_build (nto_inferior->pid, tid, 0); 00147 ti = find_thread_ptid (ptid); 00148 if (ti != NULL) 00149 { 00150 TRACE ("Removing thread %d\n", tid); 00151 remove_thread (ti); 00152 } 00153 if (tid == status.tid) 00154 break; 00155 ++tid; 00156 } 00157 00158 if (status.state != STATE_DEAD) 00159 { 00160 TRACE ("Adding thread %d\n", tid); 00161 ptid = ptid_build (nto_inferior->pid, tid, 0); 00162 if (!find_thread_ptid (ptid)) 00163 add_thread (ptid, NULL); 00164 } 00165 } 00166 } 00167 00168 /* Given pid, open procfs path. */ 00169 00170 static pid_t 00171 do_attach (pid_t pid) 00172 { 00173 procfs_status status; 00174 struct sigevent event; 00175 00176 if (nto_inferior.ctl_fd != -1) 00177 { 00178 close (nto_inferior.ctl_fd); 00179 init_nto_inferior (&nto_inferior); 00180 } 00181 xsnprintf (nto_inferior.nto_procfs_path, PATH_MAX - 1, "/proc/%d/as", pid); 00182 nto_inferior.ctl_fd = open (nto_inferior.nto_procfs_path, O_RDWR); 00183 if (nto_inferior.ctl_fd == -1) 00184 { 00185 TRACE ("Failed to open %s\n", nto_inferior.nto_procfs_path); 00186 init_nto_inferior (&nto_inferior); 00187 return -1; 00188 } 00189 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, &status, sizeof (status), 0) 00190 != EOK) 00191 { 00192 do_detach (); 00193 return -1; 00194 } 00195 nto_inferior.pid = pid; 00196 /* Define a sigevent for process stopped notification. */ 00197 event.sigev_notify = SIGEV_SIGNAL_THREAD; 00198 event.sigev_signo = SIGUSR1; 00199 event.sigev_code = 0; 00200 event.sigev_value.sival_ptr = NULL; 00201 event.sigev_priority = -1; 00202 devctl (nto_inferior.ctl_fd, DCMD_PROC_EVENT, &event, sizeof (event), 0); 00203 00204 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 00205 0) == EOK 00206 && (status.flags & _DEBUG_FLAG_STOPPED)) 00207 { 00208 ptid_t ptid; 00209 struct process_info *proc; 00210 00211 kill (pid, SIGCONT); 00212 ptid = ptid_build (status.pid, status.tid, 0); 00213 the_low_target.arch_setup (); 00214 proc = add_process (status.pid, 1); 00215 proc->tdesc = nto_tdesc; 00216 TRACE ("Adding thread: pid=%d tid=%ld\n", status.pid, 00217 ptid_get_lwp (ptid)); 00218 nto_find_new_threads (&nto_inferior); 00219 } 00220 else 00221 { 00222 do_detach (); 00223 return -1; 00224 } 00225 00226 return pid; 00227 } 00228 00229 /* Read or write LEN bytes from/to inferior's MEMADDR memory address 00230 into gdbservers's MYADDR buffer. Return number of bytes actually 00231 transfered. */ 00232 00233 static int 00234 nto_xfer_memory (off_t memaddr, unsigned char *myaddr, int len, 00235 int dowrite) 00236 { 00237 int nbytes = 0; 00238 00239 if (lseek (nto_inferior.ctl_fd, memaddr, SEEK_SET) == memaddr) 00240 { 00241 if (dowrite) 00242 nbytes = write (nto_inferior.ctl_fd, myaddr, len); 00243 else 00244 nbytes = read (nto_inferior.ctl_fd, myaddr, len); 00245 if (nbytes < 0) 00246 nbytes = 0; 00247 } 00248 if (nbytes == 0) 00249 { 00250 int e = errno; 00251 TRACE ("Error in %s : errno=%d (%s)\n", __func__, e, strerror (e)); 00252 } 00253 return nbytes; 00254 } 00255 00256 /* Insert or remove breakpoint or watchpoint at address ADDR. 00257 TYPE can be one of Neutrino breakpoint types. SIZE must be 0 for 00258 inserting the point, -1 for removing it. 00259 00260 Return 0 on success, 1 otherwise. */ 00261 00262 static int 00263 nto_breakpoint (CORE_ADDR addr, int type, int size) 00264 { 00265 procfs_break brk; 00266 00267 brk.type = type; 00268 brk.addr = addr; 00269 brk.size = size; 00270 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_BREAK, &brk, sizeof (brk), 0) 00271 != EOK) 00272 return 1; 00273 return 0; 00274 } 00275 00276 /* Read auxiliary vector from inferior's initial stack into gdbserver's 00277 MYADDR buffer, up to LEN bytes. 00278 00279 Return number of bytes read. */ 00280 00281 static int 00282 nto_read_auxv_from_initial_stack (CORE_ADDR initial_stack, 00283 unsigned char *myaddr, 00284 unsigned int len) 00285 { 00286 int data_ofs = 0; 00287 int anint; 00288 unsigned int len_read = 0; 00289 00290 /* Skip over argc, argv and envp... Comment from ldd.c: 00291 00292 The startup frame is set-up so that we have: 00293 auxv 00294 NULL 00295 ... 00296 envp2 00297 envp1 <----- void *frame + (argc + 2) * sizeof(char *) 00298 NULL 00299 ... 00300 argv2 00301 argv1 00302 argc <------ void * frame 00303 00304 On entry to ldd, frame gives the address of argc on the stack. */ 00305 if (nto_xfer_memory (initial_stack, (unsigned char *)&anint, 00306 sizeof (anint), 0) != sizeof (anint)) 00307 return 0; 00308 00309 /* Size of pointer is assumed to be 4 bytes (32 bit arch. ) */ 00310 data_ofs += (anint + 2) * sizeof (void *); /* + 2 comes from argc itself and 00311 NULL terminating pointer in 00312 argv. */ 00313 00314 /* Now loop over env table: */ 00315 while (nto_xfer_memory (initial_stack + data_ofs, 00316 (unsigned char *)&anint, sizeof (anint), 0) 00317 == sizeof (anint)) 00318 { 00319 data_ofs += sizeof (anint); 00320 if (anint == 0) 00321 break; 00322 } 00323 initial_stack += data_ofs; 00324 00325 memset (myaddr, 0, len); 00326 while (len_read <= len - sizeof (auxv_t)) 00327 { 00328 auxv_t *auxv = (auxv_t *)myaddr; 00329 00330 /* Search backwards until we have read AT_PHDR (num. 3), 00331 AT_PHENT (num 4), AT_PHNUM (num 5) */ 00332 if (nto_xfer_memory (initial_stack, (unsigned char *)auxv, 00333 sizeof (auxv_t), 0) == sizeof (auxv_t)) 00334 { 00335 if (auxv->a_type != AT_NULL) 00336 { 00337 auxv++; 00338 len_read += sizeof (auxv_t); 00339 } 00340 if (auxv->a_type == AT_PHNUM) /* That's all we need. */ 00341 break; 00342 initial_stack += sizeof (auxv_t); 00343 } 00344 else 00345 break; 00346 } 00347 TRACE ("auxv: len_read: %d\n", len_read); 00348 return len_read; 00349 } 00350 00351 /* Start inferior specified by PROGRAM passing arguments ALLARGS. */ 00352 00353 static int 00354 nto_create_inferior (char *program, char **allargs) 00355 { 00356 struct inheritance inherit; 00357 pid_t pid; 00358 sigset_t set; 00359 00360 TRACE ("%s %s\n", __func__, program); 00361 /* Clear any pending SIGUSR1's but keep the behavior the same. */ 00362 signal (SIGUSR1, signal (SIGUSR1, SIG_IGN)); 00363 00364 sigemptyset (&set); 00365 sigaddset (&set, SIGUSR1); 00366 sigprocmask (SIG_UNBLOCK, &set, NULL); 00367 00368 memset (&inherit, 0, sizeof (inherit)); 00369 inherit.flags |= SPAWN_SETGROUP | SPAWN_HOLD; 00370 inherit.pgroup = SPAWN_NEWPGROUP; 00371 pid = spawnp (program, 0, NULL, &inherit, allargs, 0); 00372 sigprocmask (SIG_BLOCK, &set, NULL); 00373 00374 if (pid == -1) 00375 return -1; 00376 00377 if (do_attach (pid) != pid) 00378 return -1; 00379 00380 return pid; 00381 } 00382 00383 /* Attach to process PID. */ 00384 00385 static int 00386 nto_attach (unsigned long pid) 00387 { 00388 TRACE ("%s %ld\n", __func__, pid); 00389 if (do_attach (pid) != pid) 00390 error ("Unable to attach to %ld\n", pid); 00391 return 0; 00392 } 00393 00394 /* Send signal to process PID. */ 00395 00396 static int 00397 nto_kill (int pid) 00398 { 00399 TRACE ("%s %d\n", __func__, pid); 00400 kill (pid, SIGKILL); 00401 do_detach (); 00402 return 0; 00403 } 00404 00405 /* Detach from process PID. */ 00406 00407 static int 00408 nto_detach (int pid) 00409 { 00410 TRACE ("%s %d\n", __func__, pid); 00411 do_detach (); 00412 return 0; 00413 } 00414 00415 static void 00416 nto_mourn (struct process_info *process) 00417 { 00418 remove_process (process); 00419 } 00420 00421 /* Check if the given thread is alive. 00422 00423 Return 1 if alive, 0 otherwise. */ 00424 00425 static int 00426 nto_thread_alive (ptid_t ptid) 00427 { 00428 int res; 00429 00430 TRACE ("%s pid:%d tid:%d\n", __func__, ptid_get_pid (ptid), 00431 ptid_get_lwp (ptid)); 00432 if (SignalKill (0, ptid_get_pid (ptid), ptid_get_lwp (ptid), 00433 0, 0, 0) == -1) 00434 res = 0; 00435 else 00436 res = 1; 00437 TRACE ("%s: %s\n", __func__, res ? "yes" : "no"); 00438 return res; 00439 } 00440 00441 /* Resume inferior's execution. */ 00442 00443 static void 00444 nto_resume (struct thread_resume *resume_info, size_t n) 00445 { 00446 /* We can only work in all-stop mode. */ 00447 procfs_status status; 00448 procfs_run run; 00449 int err; 00450 00451 TRACE ("%s\n", __func__); 00452 /* Workaround for aliasing rules violation. */ 00453 sigset_t *run_fault = (sigset_t *) (void *) &run.fault; 00454 00455 nto_set_thread (resume_info->thread); 00456 00457 run.flags = _DEBUG_RUN_FAULT | _DEBUG_RUN_TRACE; 00458 if (resume_info->kind == resume_step) 00459 run.flags |= _DEBUG_RUN_STEP; 00460 run.flags |= _DEBUG_RUN_ARM; 00461 00462 sigemptyset (run_fault); 00463 sigaddset (run_fault, FLTBPT); 00464 sigaddset (run_fault, FLTTRACE); 00465 sigaddset (run_fault, FLTILL); 00466 sigaddset (run_fault, FLTPRIV); 00467 sigaddset (run_fault, FLTBOUNDS); 00468 sigaddset (run_fault, FLTIOVF); 00469 sigaddset (run_fault, FLTIZDIV); 00470 sigaddset (run_fault, FLTFPE); 00471 sigaddset (run_fault, FLTPAGE); 00472 sigaddset (run_fault, FLTSTACK); 00473 sigaddset (run_fault, FLTACCESS); 00474 00475 sigemptyset (&run.trace); 00476 if (resume_info->sig) 00477 { 00478 int signal_to_pass; 00479 00480 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 00481 0); 00482 signal_to_pass = resume_info->sig; 00483 if (status.why & (_DEBUG_WHY_SIGNALLED | _DEBUG_WHY_FAULTED)) 00484 { 00485 if (signal_to_pass != status.info.si_signo) 00486 { 00487 kill (status.pid, signal_to_pass); 00488 run.flags |= _DEBUG_RUN_CLRFLT | _DEBUG_RUN_CLRSIG; 00489 } 00490 else /* Let it kill the program without telling us. */ 00491 sigdelset (&run.trace, signal_to_pass); 00492 } 00493 } 00494 else 00495 run.flags |= _DEBUG_RUN_CLRSIG | _DEBUG_RUN_CLRFLT; 00496 00497 sigfillset (&run.trace); 00498 00499 regcache_invalidate (); 00500 00501 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_RUN, &run, sizeof (run), 0); 00502 if (err != EOK) 00503 TRACE ("Error: %d \"%s\"\n", err, strerror (err)); 00504 } 00505 00506 /* Wait for inferior's event. 00507 00508 Return ptid of thread that caused the event. */ 00509 00510 static ptid_t 00511 nto_wait (ptid_t ptid, 00512 struct target_waitstatus *ourstatus, int target_options) 00513 { 00514 sigset_t set; 00515 siginfo_t info; 00516 procfs_status status; 00517 const int trace_mask = (_DEBUG_FLAG_TRACE_EXEC | _DEBUG_FLAG_TRACE_RD 00518 | _DEBUG_FLAG_TRACE_WR | _DEBUG_FLAG_TRACE_MODIFY); 00519 00520 TRACE ("%s\n", __func__); 00521 00522 ourstatus->kind = TARGET_WAITKIND_SPURIOUS; 00523 00524 sigemptyset (&set); 00525 sigaddset (&set, SIGUSR1); 00526 00527 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 0); 00528 while (!(status.flags & _DEBUG_FLAG_ISTOP)) 00529 { 00530 sigwaitinfo (&set, &info); 00531 devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, sizeof (status), 00532 0); 00533 } 00534 nto_find_new_threads (&nto_inferior); 00535 00536 if (status.flags & _DEBUG_FLAG_SSTEP) 00537 { 00538 TRACE ("SSTEP\n"); 00539 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00540 ourstatus->value.sig = GDB_SIGNAL_TRAP; 00541 } 00542 /* Was it a breakpoint? */ 00543 else if (status.flags & trace_mask) 00544 { 00545 TRACE ("STOPPED\n"); 00546 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00547 ourstatus->value.sig = GDB_SIGNAL_TRAP; 00548 } 00549 else if (status.flags & _DEBUG_FLAG_ISTOP) 00550 { 00551 TRACE ("ISTOP\n"); 00552 switch (status.why) 00553 { 00554 case _DEBUG_WHY_SIGNALLED: 00555 TRACE (" SIGNALLED\n"); 00556 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00557 ourstatus->value.sig = 00558 gdb_signal_from_host (status.info.si_signo); 00559 nto_inferior.exit_signo = ourstatus->value.sig; 00560 break; 00561 case _DEBUG_WHY_FAULTED: 00562 TRACE (" FAULTED\n"); 00563 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00564 if (status.info.si_signo == SIGTRAP) 00565 { 00566 ourstatus->value.sig = 0; 00567 nto_inferior.exit_signo = 0; 00568 } 00569 else 00570 { 00571 ourstatus->value.sig = 00572 gdb_signal_from_host (status.info.si_signo); 00573 nto_inferior.exit_signo = ourstatus->value.sig; 00574 } 00575 break; 00576 00577 case _DEBUG_WHY_TERMINATED: 00578 { 00579 int waitval = 0; 00580 00581 TRACE (" TERMINATED\n"); 00582 waitpid (ptid_get_pid (ptid), &waitval, WNOHANG); 00583 if (nto_inferior.exit_signo) 00584 { 00585 /* Abnormal death. */ 00586 ourstatus->kind = TARGET_WAITKIND_SIGNALLED; 00587 ourstatus->value.sig = nto_inferior.exit_signo; 00588 } 00589 else 00590 { 00591 /* Normal death. */ 00592 ourstatus->kind = TARGET_WAITKIND_EXITED; 00593 ourstatus->value.integer = WEXITSTATUS (waitval); 00594 } 00595 nto_inferior.exit_signo = 0; 00596 break; 00597 } 00598 00599 case _DEBUG_WHY_REQUESTED: 00600 TRACE ("REQUESTED\n"); 00601 /* We are assuming a requested stop is due to a SIGINT. */ 00602 ourstatus->kind = TARGET_WAITKIND_STOPPED; 00603 ourstatus->value.sig = GDB_SIGNAL_INT; 00604 nto_inferior.exit_signo = 0; 00605 break; 00606 } 00607 } 00608 00609 return ptid_build (status.pid, status.tid, 0); 00610 } 00611 00612 /* Fetch inferior's registers for currently selected thread (CURRENT_INFERIOR). 00613 If REGNO is -1, fetch all registers, or REGNO register only otherwise. */ 00614 00615 static void 00616 nto_fetch_registers (struct regcache *regcache, int regno) 00617 { 00618 int regsize; 00619 procfs_greg greg; 00620 ptid_t ptid; 00621 00622 TRACE ("%s (regno=%d)\n", __func__, regno); 00623 if (regno >= the_low_target.num_regs) 00624 return; 00625 00626 if (current_inferior == NULL) 00627 { 00628 TRACE ("current_inferior is NULL\n"); 00629 return; 00630 } 00631 ptid = thread_to_gdb_id (current_inferior); 00632 if (!nto_set_thread (ptid)) 00633 return; 00634 00635 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_GETGREG, &greg, sizeof (greg), 00636 ®size) == EOK) 00637 { 00638 if (regno == -1) /* All registers. */ 00639 { 00640 for (regno = 0; regno != the_low_target.num_regs; ++regno) 00641 { 00642 const unsigned int registeroffset 00643 = the_low_target.register_offset (regno); 00644 supply_register (regcache, regno, 00645 ((char *)&greg) + registeroffset); 00646 } 00647 } 00648 else 00649 { 00650 const unsigned int registeroffset 00651 = the_low_target.register_offset (regno); 00652 if (registeroffset == -1) 00653 return; 00654 supply_register (regcache, regno, ((char *)&greg) + registeroffset); 00655 } 00656 } 00657 else 00658 TRACE ("ERROR reading registers from inferior.\n"); 00659 } 00660 00661 /* Store registers for currently selected thread (CURRENT_INFERIOR). 00662 We always store all registers, regardless of REGNO. */ 00663 00664 static void 00665 nto_store_registers (struct regcache *regcache, int regno) 00666 { 00667 procfs_greg greg; 00668 int err; 00669 ptid_t ptid; 00670 00671 TRACE ("%s (regno:%d)\n", __func__, regno); 00672 00673 if (current_inferior == NULL) 00674 { 00675 TRACE ("current_inferior is NULL\n"); 00676 return; 00677 } 00678 ptid = thread_to_gdb_id (current_inferior); 00679 if (!nto_set_thread (ptid)) 00680 return; 00681 00682 memset (&greg, 0, sizeof (greg)); 00683 for (regno = 0; regno != the_low_target.num_regs; ++regno) 00684 { 00685 const unsigned int regoffset 00686 = the_low_target.register_offset (regno); 00687 collect_register (regcache, regno, ((char *)&greg) + regoffset); 00688 } 00689 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_SETGREG, &greg, sizeof (greg), 00690 0); 00691 if (err != EOK) 00692 TRACE ("Error: setting registers.\n"); 00693 } 00694 00695 /* Read LEN bytes from inferior's memory address MEMADDR into 00696 gdbserver's MYADDR buffer. 00697 00698 Return 0 on success -1 otherwise. */ 00699 00700 static int 00701 nto_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) 00702 { 00703 TRACE ("%s memaddr:0x%08lx, len:%d\n", __func__, memaddr, len); 00704 00705 if (nto_xfer_memory (memaddr, myaddr, len, 0) != len) 00706 { 00707 TRACE ("Failed to read memory\n"); 00708 return -1; 00709 } 00710 00711 return 0; 00712 } 00713 00714 /* Write LEN bytes from gdbserver's buffer MYADDR into inferior's 00715 memory at address MEMADDR. 00716 00717 Return 0 on success -1 otherwise. */ 00718 00719 static int 00720 nto_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len) 00721 { 00722 int len_written; 00723 00724 TRACE ("%s memaddr: 0x%08llx len: %d\n", __func__, memaddr, len); 00725 if ((len_written = nto_xfer_memory (memaddr, (unsigned char *)myaddr, len, 00726 1)) 00727 != len) 00728 { 00729 TRACE ("Wanted to write: %d but written: %d\n", len, len_written); 00730 return -1; 00731 } 00732 00733 return 0; 00734 } 00735 00736 /* Stop inferior. We always stop all threads. */ 00737 00738 static void 00739 nto_request_interrupt (void) 00740 { 00741 TRACE ("%s\n", __func__); 00742 nto_set_thread (ptid_build (nto_inferior.pid, 1, 0)); 00743 if (EOK != devctl (nto_inferior.ctl_fd, DCMD_PROC_STOP, NULL, 0, 0)) 00744 TRACE ("Error stopping inferior.\n"); 00745 } 00746 00747 /* Read auxiliary vector from inferior's memory into gdbserver's buffer 00748 MYADDR. We always read whole auxv. 00749 00750 Return number of bytes stored in MYADDR buffer, 0 if OFFSET > 0 00751 or -1 on error. */ 00752 00753 static int 00754 nto_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len) 00755 { 00756 int err; 00757 CORE_ADDR initial_stack; 00758 procfs_info procinfo; 00759 00760 TRACE ("%s\n", __func__); 00761 if (offset > 0) 00762 return 0; 00763 00764 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_INFO, &procinfo, 00765 sizeof procinfo, 0); 00766 if (err != EOK) 00767 return -1; 00768 00769 initial_stack = procinfo.initial_stack; 00770 00771 return nto_read_auxv_from_initial_stack (initial_stack, myaddr, len); 00772 } 00773 00774 /* Insert {break/watch}point at address ADDR. 00775 TYPE must be in '0'..'4' range. LEN is not used. */ 00776 00777 static int 00778 nto_insert_point (char type, CORE_ADDR addr, int len) 00779 { 00780 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */ 00781 00782 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len); 00783 switch (type) 00784 { 00785 case '0': /* software-breakpoint */ 00786 wtype = _DEBUG_BREAK_EXEC; 00787 break; 00788 case '1': /* hardware-breakpoint */ 00789 wtype |= _DEBUG_BREAK_EXEC; 00790 break; 00791 case '2': /* write watchpoint */ 00792 wtype |= _DEBUG_BREAK_RW; 00793 break; 00794 case '3': /* read watchpoint */ 00795 wtype |= _DEBUG_BREAK_RD; 00796 break; 00797 case '4': /* access watchpoint */ 00798 wtype |= _DEBUG_BREAK_RW; 00799 break; 00800 default: 00801 return 1; /* Not supported. */ 00802 } 00803 return nto_breakpoint (addr, wtype, 0); 00804 } 00805 00806 /* Remove {break/watch}point at address ADDR. 00807 TYPE must be in '0'..'4' range. LEN is not used. */ 00808 00809 static int 00810 nto_remove_point (char type, CORE_ADDR addr, int len) 00811 { 00812 int wtype = _DEBUG_BREAK_HW; /* Always request HW. */ 00813 00814 TRACE ("%s type:%c addr: 0x%08lx len:%d\n", __func__, (int)type, addr, len); 00815 switch (type) 00816 { 00817 case '0': /* software-breakpoint */ 00818 wtype = _DEBUG_BREAK_EXEC; 00819 break; 00820 case '1': /* hardware-breakpoint */ 00821 wtype |= _DEBUG_BREAK_EXEC; 00822 break; 00823 case '2': /* write watchpoint */ 00824 wtype |= _DEBUG_BREAK_RW; 00825 break; 00826 case '3': /* read watchpoint */ 00827 wtype |= _DEBUG_BREAK_RD; 00828 break; 00829 case '4': /* access watchpoint */ 00830 wtype |= _DEBUG_BREAK_RW; 00831 break; 00832 default: 00833 return 1; /* Not supported. */ 00834 } 00835 return nto_breakpoint (addr, wtype, -1); 00836 } 00837 00838 /* Check if the reason of stop for current thread (CURRENT_INFERIOR) is 00839 a watchpoint. 00840 00841 Return 1 if stopped by watchpoint, 0 otherwise. */ 00842 00843 static int 00844 nto_stopped_by_watchpoint (void) 00845 { 00846 int ret = 0; 00847 00848 TRACE ("%s\n", __func__); 00849 if (nto_inferior.ctl_fd != -1 && current_inferior != NULL) 00850 { 00851 ptid_t ptid; 00852 00853 ptid = thread_to_gdb_id (current_inferior); 00854 if (nto_set_thread (ptid)) 00855 { 00856 const int watchmask = _DEBUG_FLAG_TRACE_RD | _DEBUG_FLAG_TRACE_WR 00857 | _DEBUG_FLAG_TRACE_MODIFY; 00858 procfs_status status; 00859 int err; 00860 00861 err = devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, 00862 sizeof (status), 0); 00863 if (err == EOK && (status.flags & watchmask)) 00864 ret = 1; 00865 } 00866 } 00867 TRACE ("%s: %s\n", __func__, ret ? "yes" : "no"); 00868 return ret; 00869 } 00870 00871 /* Get instruction pointer for CURRENT_INFERIOR thread. 00872 00873 Return inferior's instruction pointer value, or 0 on error. */ 00874 00875 static CORE_ADDR 00876 nto_stopped_data_address (void) 00877 { 00878 CORE_ADDR ret = (CORE_ADDR)0; 00879 00880 TRACE ("%s\n", __func__); 00881 if (nto_inferior.ctl_fd != -1 && current_inferior != NULL) 00882 { 00883 ptid_t ptid; 00884 00885 ptid = thread_to_gdb_id (current_inferior); 00886 00887 if (nto_set_thread (ptid)) 00888 { 00889 procfs_status status; 00890 00891 if (devctl (nto_inferior.ctl_fd, DCMD_PROC_STATUS, &status, 00892 sizeof (status), 0) == EOK) 00893 ret = status.ip; 00894 } 00895 } 00896 TRACE ("%s: 0x%08lx\n", __func__, ret); 00897 return ret; 00898 } 00899 00900 /* We do not currently support non-stop. */ 00901 00902 static int 00903 nto_supports_non_stop (void) 00904 { 00905 TRACE ("%s\n", __func__); 00906 return 0; 00907 } 00908 00909 00910 00911 static struct target_ops nto_target_ops = { 00912 nto_create_inferior, 00913 nto_attach, 00914 nto_kill, 00915 nto_detach, 00916 nto_mourn, 00917 NULL, /* nto_join */ 00918 nto_thread_alive, 00919 nto_resume, 00920 nto_wait, 00921 nto_fetch_registers, 00922 nto_store_registers, 00923 NULL, /* prepare_to_access_memory */ 00924 NULL, /* done_accessing_memory */ 00925 nto_read_memory, 00926 nto_write_memory, 00927 NULL, /* nto_look_up_symbols */ 00928 nto_request_interrupt, 00929 nto_read_auxv, 00930 nto_insert_point, 00931 nto_remove_point, 00932 nto_stopped_by_watchpoint, 00933 nto_stopped_data_address, 00934 NULL, /* nto_read_offsets */ 00935 NULL, /* thread_db_set_tls_address */ 00936 NULL, 00937 hostio_last_error_from_errno, 00938 NULL, /* nto_qxfer_osdata */ 00939 NULL, /* xfer_siginfo */ 00940 nto_supports_non_stop, 00941 NULL, /* async */ 00942 NULL /* start_non_stop */ 00943 }; 00944 00945 00946 /* Global function called by server.c. Initializes QNX Neutrino 00947 gdbserver. */ 00948 00949 void 00950 initialize_low (void) 00951 { 00952 sigset_t set; 00953 00954 TRACE ("%s\n", __func__); 00955 set_target_ops (&nto_target_ops); 00956 set_breakpoint_data (the_low_target.breakpoint, 00957 the_low_target.breakpoint_len); 00958 00959 /* We use SIGUSR1 to gain control after we block waiting for a process. 00960 We use sigwaitevent to wait. */ 00961 sigemptyset (&set); 00962 sigaddset (&set, SIGUSR1); 00963 sigprocmask (SIG_BLOCK, &set, NULL); 00964 } 00965