/* * In order to read from a block-oriented device, we pick up the seek pointer, * read each containing block, and then copy the desired range of bytes back * into the caller's buffer. Unfortunately Solaris hardcodes the notion of * DEV_BSIZE as the transfer unit for such devices; no ioctl() to obtain the * transfer unit dynamically is currently available. At the end of the * transfer we reset the seek pointer to where the caller thinks it should be. */ static ssize_t fdio_bdev_read(mdb_io_t *io, void *buf, size_t nbytes) { fd_data_t *fdp = io->io_data; ssize_t resid = nbytes; uchar_t blk[DEV_BSIZE]; off64_t off; if (io->io_next != NULL) return (IOP_READ(io->io_next, buf, nbytes)); if ((off = lseek64(fdp->fd_fd, 0, SEEK_CUR)) == -1) return (-1); /* errno is set for us */ while (resid != 0) { off64_t devoff = off & ~(DEV_BSIZE - 1); size_t blkoff = off & (DEV_BSIZE - 1); size_t len = MIN(resid, DEV_BSIZE - blkoff); if (pread64(fdp->fd_fd, blk, DEV_BSIZE, devoff) != DEV_BSIZE) break; /* errno is set for us, unless EOF */ bcopy(&blk[blkoff], buf, len); resid -= len; off += len; buf = (char *)buf + len; } if (resid == nbytes && nbytes != 0) return (set_errno(EMDB_EOF)); (void) lseek64(fdp->fd_fd, off, SEEK_SET); return (nbytes - resid); }
static ssize_t pio_read(mdb_io_t *io, void *buf, size_t nbytes) { pio_data_t *pdp = io->io_data; if (io->io_next == NULL) return (kmdb_prom_read(buf, nbytes, &pdp->pio_ti)); return (IOP_READ(io->io_next, buf, nbytes)); }
static ssize_t fdio_read(mdb_io_t *io, void *buf, size_t nbytes) { fd_data_t *fdp = io->io_data; if (io->io_next == NULL) return (read(fdp->fd_fd, buf, nbytes)); return (IOP_READ(io->io_next, buf, nbytes)); }
void seeki_add(void *handle, struct io *iop) { struct seeki *sip = handle; char rw = IOP_READ(iop) ? 'r' : 'w'; long long dist = seek_dist(sip, iop); double tstamp = BIT_TIME(iop->t.time); FILE *fp = IOP_READ(iop) ? sip->rfp : sip->wfp; if (fp) fprintf(fp, "%15.9lf %13lld %c\n", tstamp, dist, rw); if (sip->cfp) fprintf(sip->cfp, "%15.9lf %13lld %c\n", tstamp, dist, rw); dist = llabs(dist); sip->tot_seeks++; sip->total_sectors += dist; __insert(&sip->root, dist); sps_add(sip, tstamp); }
char kmdb_getchar(void) { char c; while (IOP_READ(mdb.m_term, &c, 1) != 1) continue; if (isprint(c) && c != '\n') mdb_iob_printf(mdb.m_out, "%c", c); mdb_iob_printf(mdb.m_out, "\n"); return (c); }
static ssize_t memio_read(mdb_io_t *io, void *buf, size_t nbytes) { mem_data_t *mdp = io->io_data; if (io->io_next == NULL) { if (mdp->md_off + nbytes > mdp->md_size) nbytes = (mdp->md_size - mdp->md_off); bcopy(mdp->md_buf + mdp->md_off, buf, nbytes); mdp->md_off += nbytes; return (nbytes); } return (IOP_READ(io->io_next, buf, nbytes)); }
static ssize_t rf_read(mdb_io_t *io, void *buf, size_t nbytes, uint64_t addr) { ssize_t rbytes; if (io == NULL) return (set_errno(EMDB_NOMAP)); if (IOP_SEEK(io, addr, SEEK_SET) == -1) return (-1); /* errno is set for us */ if ((rbytes = IOP_READ(io, buf, nbytes)) == 0) (void) set_errno(EMDB_EOF); return (rbytes); }
static ssize_t logio_read(mdb_io_t *io, void *buf, size_t nbytes) { mdb_io_t *logio = io->io_data; ssize_t rbytes; if (io->io_next != NULL) { rbytes = IOP_READ(io->io_next, buf, nbytes); if (rbytes > 0) { (void) IOP_WRITE(logio, mdb.m_prompt, mdb.m_promptlen); (void) IOP_WRITE(logio, buf, rbytes); } return (rbytes); } return (-1); }
/*ARGSUSED*/ static void flt_handler(int sig, siginfo_t *sip, ucontext_t *ucp, void *data) { static const struct rlimit rl = { (rlim_t)RLIM_INFINITY, (rlim_t)RLIM_INFINITY }; const mdb_idcmd_t *idcp = NULL; if (mdb.m_frame != NULL && mdb.m_frame->f_cp != NULL) idcp = mdb.m_frame->f_cp->c_dcmd; if (sip != NULL) bcopy(sip, &_mdb_abort_info, sizeof (_mdb_abort_info)); if (ucp != NULL) bcopy(ucp, &_mdb_abort_ctx, sizeof (_mdb_abort_ctx)); _mdb_abort_info.si_signo = sig; (void) mdb_signal_sethandler(sig, SIG_DFL, NULL); /* * If there is no current dcmd, or the current dcmd comes from a * builtin module, we don't allow resume and always core dump. */ if (idcp == NULL || idcp->idc_modp == NULL || idcp->idc_modp == &mdb.m_rmod || idcp->idc_modp->mod_hdl == NULL) goto dump; if (mdb.m_term != NULL) { struct frame *fr = (struct frame *) (ucp->uc_mcontext.gregs[STACK_REGISTER] + STACK_BIAS); char signame[SIG2STR_MAX]; int i = 1; char c; if (sig2str(sig, signame) == -1) { mdb_iob_printf(mdb.m_err, "\n*** %s: received signal %d at:\n", mdb.m_pname, sig); } else { mdb_iob_printf(mdb.m_err, "\n*** %s: received signal %s at:\n", mdb.m_pname, signame); } if (ucp->uc_mcontext.gregs[REG_PC] != 0) print_frame(ucp->uc_mcontext.gregs[REG_PC], i++); while (fr != NULL && valid_frame(fr) && fr->fr_savpc != 0) { print_frame(fr->fr_savpc, i++); fr = (struct frame *) ((uintptr_t)fr->fr_savfp + STACK_BIAS); } query: mdb_iob_printf(mdb.m_err, "\n%s: (c)ore dump, (q)uit, " "(r)ecover, or (s)top for debugger [cqrs]? ", mdb.m_pname); mdb_iob_flush(mdb.m_err); for (;;) { if (IOP_READ(mdb.m_term, &c, sizeof (c)) != sizeof (c)) goto dump; switch (c) { case 'c': case 'C': (void) setrlimit(RLIMIT_CORE, &rl); mdb_iob_printf(mdb.m_err, "\n%s: attempting " "to dump core ...\n", mdb.m_pname); goto dump; case 'q': case 'Q': mdb_iob_discard(mdb.m_out); mdb_iob_nl(mdb.m_err); (void) mdb_signal_unblockall(); terminate(1); /*NOTREACHED*/ case 'r': case 'R': mdb_iob_printf(mdb.m_err, "\n%s: unloading " "module '%s' ...\n", mdb.m_pname, idcp->idc_modp->mod_name); (void) mdb_module_unload( idcp->idc_modp->mod_name, 0); (void) mdb_signal_sethandler(sig, flt_handler, NULL); _mdb_abort_rcount++; mdb.m_intr = 0; mdb.m_pend = 0; (void) mdb_signal_unblockall(); longjmp(mdb.m_frame->f_pcb, MDB_ERR_ABORT); /*NOTREACHED*/ case 's': case 'S': mdb_iob_printf(mdb.m_err, "\n%s: " "attempting to stop pid %d ...\n", mdb.m_pname, (int)getpid()); /* * Stop ourself; if this fails or we are * subsequently continued, ask again. */ (void) mdb_signal_raise(SIGSTOP); (void) mdb_signal_unblockall(); goto query; } } } dump: if (SI_FROMUSER(sip)) { (void) mdb_signal_block(sig); (void) mdb_signal_raise(sig); } (void) sigfillset(&ucp->uc_sigmask); (void) sigdelset(&ucp->uc_sigmask, sig); if (_mdb_abort_str == NULL) _mdb_abort_str = "fatal signal received"; ucp->uc_flags |= UC_SIGMASK; (void) setcontext(ucp); }