/* * Call an internal dcmd directly: this code is used by module API functions * that need to execute dcmds, and by mdb_call() above. */ int mdb_call_idcmd(mdb_idcmd_t *idcp, uintmax_t addr, uintmax_t count, uint_t flags, mdb_argvec_t *avp, mdb_addrvec_t *adp, mdb_vcb_t *vcbs) { int is_exec = (strcmp(idcp->idc_name, "$<") == 0); mdb_arg_t *argv; int argc; uintmax_t i; int status; /* * Update the values of dot and the most recent address and count * to the values of our input parameters. */ mdb_nv_set_value(mdb.m_dot, addr); mdb.m_raddr = addr; mdb.m_dcount = count; /* * Here the adb(1) man page lies: '9' is only set to count * when the command is $<, not when it's $<<. */ if (is_exec) mdb_nv_set_value(mdb.m_rcount, count); /* * We can now return if the repeat count is zero. */ if (count == 0) return (DCMD_OK); /* * To guard against bad dcmds, we avoid passing the actual argv that * we will use to free argument strings directly to the dcmd. Instead, * we pass a copy that will be garbage collected automatically. */ argc = avp->a_nelems; argv = mdb_alloc(sizeof (mdb_arg_t) * argc, UM_SLEEP | UM_GC); bcopy(avp->a_data, argv, sizeof (mdb_arg_t) * argc); if (mdb_addrvec_length(adp) != 0) { flags |= DCMD_PIPE | DCMD_LOOP | DCMD_LOOPFIRST | DCMD_ADDRSPEC; addr = mdb_addrvec_shift(adp); mdb_nv_set_value(mdb.m_dot, addr); mdb_vcb_propagate(vcbs); count = 1; } status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs); if (DCMD_ABORTED(status)) goto done; /* * If the command is $< and we're not receiving input from a pipe, we * ignore the repeat count and just return since the macro file is now * pushed on to the input stack. */ if (is_exec && mdb_addrvec_length(adp) == 0) goto done; /* * If we're going to loop, we've already executed the dcmd once, * so clear the LOOPFIRST flag before proceeding. */ if (flags & DCMD_LOOP) flags &= ~DCMD_LOOPFIRST; for (i = 1; i < count; i++) { addr = mdb_dot_incr(","); mdb_nv_set_value(mdb.m_dot, addr); status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs); if (DCMD_ABORTED(status)) goto done; } while (mdb_addrvec_length(adp) != 0) { addr = mdb_addrvec_shift(adp); mdb_nv_set_value(mdb.m_dot, addr); mdb_vcb_propagate(vcbs); status = dcmd_invoke(idcp, addr, flags, argc, argv, vcbs); if (DCMD_ABORTED(status)) goto done; } done: mdb_iob_nlflush(mdb.m_out); return (status); }
static void roff_disc_set(mdb_var_t *v, uintmax_t value) { mdb_nv_set_value(mdb.m_proffset, MDB_NV_VALUE(v)); MDB_NV_VALUE(v) = value; }
void mdb_set_dot(uintmax_t addr) { mdb_nv_set_value(mdb.m_dot, addr); mdb.m_incr = 0; }