]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
Implementation for tracing stub-based system calls. Due to the need for
authorKris Van Hees <kris.van.hees@oracle.com>
Thu, 27 Oct 2011 14:39:19 +0000 (10:39 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Thu, 27 Oct 2011 14:39:19 +0000 (10:39 -0400)
specialized code handling (mainly passing in a pt_regs structure as one of
the arguments), some syscalls are called through a stub in assembly code.
We duplicate the stub cdode in dtrace_stubs_x86_64.S, but instead of calling
the actual syscall implementation code call our own syscall-specific handler,
which ensures that entry and return probes are called as enabled, and then
call the underlying implementation directly for handling the syscall.

Also removed debugging output that is no longer relevant (code cleanup).

Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
dtrace/dtrace_dev.c
dtrace/dtrace_ecb.c
dtrace/dtrace_isa.c
dtrace/dtrace_probe.c
dtrace/dtrace_ptofapi.c
dtrace/dtrace_spec.c
dtrace/dtrace_state.c
dtrace/profile_dev.c
dtrace/systrace_dev.c

index e76497f6555c91b8199d0d5e05216d0fdf365dc1..821ef540b2847a656474d913a141180cea407177 100644 (file)
@@ -109,7 +109,6 @@ static long dtrace_ioctl(struct file *file,
                dtrace_providerdesc_t   pvd;
                dtrace_provider_t       *pvp;
 
-printk(KERN_INFO "IOCTL provider\n");
                if (copy_from_user(&pvd, argp, sizeof(pvd)) != 0)
                        return -EFAULT;
 
@@ -146,26 +145,21 @@ printk(KERN_INFO "IOCTL provider\n");
                uint8_t                 *dest;
                int                     nrecs;
 
-printk(KERN_INFO "IOCTL eprobe\n");
                if (copy_from_user(&epdesc, argp, sizeof(epdesc)) != 0)
                        return -EFAULT;
 
                mutex_lock(&dtrace_lock);
 
-printk(KERN_INFO "    Looking for ECB %ld\n", epdesc.dtepd_epid);
                if ((ecb = dtrace_epid2ecb(state, epdesc.dtepd_epid)) == NULL) {
                        mutex_unlock(&dtrace_lock);
-printk(KERN_INFO "    ECB not found\n");
                        return -EINVAL;
                }
 
                if (ecb->dte_probe == NULL) {
                        mutex_unlock(&dtrace_lock);
-printk(KERN_INFO "    ECB has no probe\n");
                        return -EINVAL;
                }
 
-printk(KERN_INFO "    ECB has probe %ld\n", ecb->dte_probe->dtpr_id);
                epdesc.dtepd_probeid = ecb->dte_probe->dtpr_id;
                epdesc.dtepd_uarg = ecb->dte_uarg;
                epdesc.dtepd_size = ecb->dte_size;
@@ -228,7 +222,6 @@ printk(KERN_INFO "    ECB has probe %ld\n", ecb->dte_probe->dtpr_id);
                size_t                  size;
                uint8_t                 *dest;
 
-printk(KERN_INFO "IOCTL aggdesc\n");
                if (copy_from_user(&aggdesc, argp, sizeof(aggdesc)) != 0)
                        return -EFAULT;
 
@@ -238,7 +231,6 @@ printk(KERN_INFO "IOCTL aggdesc\n");
                        mutex_unlock(&dtrace_lock);
                        return -EINVAL;
                }
-printk(KERN_INFO "IOCTL aggdesc: Found agg %lu, ECB %lu\n", agg->dtag_id, agg->dtag_ecb->dte_epid);
 
                aggdesc.dtagd_epid = agg->dtag_ecb->dte_epid;
 
@@ -330,7 +322,6 @@ printk(KERN_INFO "IOCTL aggdesc: Found agg %lu, ECB %lu\n", agg->dtag_id, agg->d
                int                     err = 0;
                int                     rv;
 
-printk(KERN_INFO "IOCTL enable\n");
                rv = 0;
 
                /*
@@ -391,7 +382,6 @@ printk(KERN_INFO "IOCTL enable\n");
                dtrace_probedesc_t      *create = &desc.dtrpd_create;
                int                     err;
 
-printk(KERN_INFO "IOCTL replicate\n");
                if (copy_from_user(&desc, argp, sizeof(desc)) != 0)
                        return -EFAULT;
 
@@ -420,7 +410,6 @@ printk(KERN_INFO "IOCTL replicate\n");
                uint32_t                priv;
                uid_t                   uid;
 
-printk(KERN_INFO "IOCTL %s\n", cmd == DTRACEIOC_PROBEMATCH ? "probematch" : "probes");
                if (copy_from_user(&desc, argp, sizeof(desc)) != 0)
                        return -EFAULT;
 
@@ -443,7 +432,6 @@ printk(KERN_INFO "IOCTL %s\n", cmd == DTRACEIOC_PROBEMATCH ? "probematch" : "pro
                        dtrace_probekey(&desc, &pkey);
                        pkey.dtpk_id = DTRACE_IDNONE;
                }
-printk(KERN_INFO "IOCTL %s: id[%d] p[%s] m[%s] f[%s] n[%s]\n", cmd == DTRACEIOC_PROBEMATCH ? "probematch" : "probes", desc.dtpd_id, desc.dtpd_provider, desc.dtpd_mod, desc.dtpd_func, desc.dtpd_name);
 
                dtrace_cred2priv(file->f_cred, &priv, &uid);
 
@@ -483,7 +471,6 @@ printk(KERN_INFO "IOCTL %s: id[%d] p[%s] m[%s] f[%s] n[%s]\n", cmd == DTRACEIOC_
                dtrace_probe_description(probe, &desc);
                mutex_unlock(&dtrace_lock);
 
-printk(KERN_INFO "Returning probe [%s]\n", desc.dtpd_name);
                if (copy_to_user(argp, &desc, sizeof(desc)) != 0)
                        return -EFAULT;
 
@@ -495,7 +482,6 @@ printk(KERN_INFO "Returning probe [%s]\n", desc.dtpd_name);
                dtrace_probe_t          *probe;
                dtrace_provider_t       *prov;
 
-printk(KERN_INFO "IOCTL probearg\n");
                if (copy_from_user(&desc, argp, sizeof(desc)) != 0)
                        return -EFAULT;
 
@@ -550,7 +536,6 @@ printk(KERN_INFO "IOCTL probearg\n");
        case DTRACEIOC_GO: {
                processorid_t   cpuid;
 
-printk(KERN_INFO "IOCTL go\n");
                rval = dtrace_state_go(state, &cpuid);
 
                if (rval != 0)
@@ -565,7 +550,6 @@ printk(KERN_INFO "IOCTL go\n");
        case DTRACEIOC_STOP: {
                processorid_t   cpuid;
 
-printk(KERN_INFO "IOCTL stop\n");
                mutex_lock(&dtrace_lock);
                rval = dtrace_state_stop(state, &cpuid);
                mutex_unlock(&dtrace_lock);
@@ -583,7 +567,6 @@ printk(KERN_INFO "IOCTL stop\n");
                dof_hdr_t       hdr, *dof;
                uint64_t        len;
 
-printk(KERN_INFO "IOCTL dofget\n");
                if (copy_from_user(&hdr, argp, sizeof(hdr)) != 0)
                        return -EFAULT;
 
@@ -604,7 +587,6 @@ printk(KERN_INFO "IOCTL dofget\n");
                caddr_t                 cached;
                dtrace_buffer_t         *buf;
 
-printk(KERN_INFO "IOCTL %s\n", cmd == DTRACEIOC_AGGSNAP ? "aggsnap" : "bufsnap");
                if (copy_from_user(&desc, argp, sizeof(desc)) != 0)
                        return -EFAULT;
 
@@ -731,7 +713,6 @@ printk(KERN_INFO "IOCTL %s\n", cmd == DTRACEIOC_AGGSNAP ? "aggsnap" : "bufsnap")
        case DTRACEIOC_CONF: {
                dtrace_conf_t   conf;
 
-printk(KERN_INFO "IOCTL conf\n");
                memset(&conf, 0, sizeof(conf));
                conf.dtc_difversion = DIF_VERSION;
                conf.dtc_difintregs = DIF_DIR_NREGS;
@@ -751,7 +732,6 @@ printk(KERN_INFO "IOCTL conf\n");
                int             i, j;
                uint64_t        nerrs;
 
-printk(KERN_INFO "IOCTL status\n");
                /*
                 * See the comment in dtrace_state_deadman() for the reason
                 * for setting dts_laststatus to INT64_MAX before setting
@@ -819,7 +799,6 @@ printk(KERN_INFO "IOCTL status\n");
                char                    *str;
                int                     len;
 
-printk(KERN_INFO "IOCTL format\n");
                if (copy_from_user(&fmt, argp, sizeof (fmt)) != 0)
                        return -EFAULT;
 
index ed65ec025dc8611c1c26815623782db05a10014b..9541a0ec087232dc5bbe93f93c83146e7f15356e 100644 (file)
@@ -148,7 +148,6 @@ again:
        }
 
        agg->dtag_id = aggid;
-printk(KERN_INFO "New aggregation: %u (for ECB %u)\n", aggid, ecb->dte_epid);
 
        frec = &agg->dtag_first->dta_rec;
        if (frec->dtrd_alignment < sizeof(dtrace_aggid_t))
@@ -574,7 +573,6 @@ static dtrace_ecb_t *dtrace_ecb_add(dtrace_state_t *state,
 
        state->dts_ecbs[(ecb->dte_epid = epid) - 1] = ecb;
 
-printk(KERN_INFO "ecb_add: ECB %u for probe ID %u\n", epid, probe ? probe->dtpr_id : 0xffff);
        return ecb;
 }
 
index a767be6bf9f432dbaa4a154efafe1ffe2b657f2b..3628ad2098bb268a685d3ddf757358fe75f8a475 100644 (file)
@@ -148,7 +148,6 @@ uint64_t dtrace_getarg(int arg, int aframes)
 #endif
        int             nreg = sizeof(regmap) / sizeof(regmap[0]) - 1;
 
-printk(KERN_INFO "getarg(%d, %d) -> nreg = %d\n", arg, aframes, nreg);
        for (i = 1; i <= aframes; i++) {
                fp = fp->fr_savfp;
 
@@ -173,7 +172,6 @@ printk(KERN_INFO "getarg(%d, %d) -> nreg = %d\n", arg, aframes, nreg);
        arg++;
 
 #ifndef __i386__
-printk(KERN_INFO "getarg(%d, %d) [!i386]-> nreg = %d\n", arg, aframes, nreg);
        if (arg <= nreg) {
                /*
                 * This should not happen.  If the argument was passed in a
index 35e660671787a38f4e653de150cc1fab226b2856..771b813c81e19dc1289b37c88ce85935aaaeff2b 100644 (file)
@@ -96,7 +96,6 @@ again:
        if (provider != dtrace_provider)
                mutex_unlock(&dtrace_lock);
 
-printk(KERN_INFO "probe_create(%s, %s, %s, %s) -> %d\n", provider->dtpv_name, mod, func, name, id);
        return id;
 }
 EXPORT_SYMBOL(dtrace_probe_create);
@@ -118,7 +117,7 @@ int dtrace_probe_enable(const dtrace_probedesc_t *desc, dtrace_enabling_t *enab)
        dtrace_probekey(desc, &pkey);
        dtrace_cred2priv(enab->dten_vstate->dtvs_state->dts_cred.dcr_cred,
                         &priv, &uid);
-printk(KERN_INFO "probe_enable(%d, %s, %s, %s, %s)\n", pkey.dtpk_id, pkey.dtpk_prov, pkey.dtpk_mod, pkey.dtpk_func, pkey.dtpk_name);
+
        return dtrace_match(&pkey, priv, uid, dtrace_ecb_create_enable, enab);
 }
 
index 920ddd7e112416424b4e6653fc5e810dba09d215..88df66704cd49e9eab551662e87496dd2d375b55 100644 (file)
@@ -242,7 +242,6 @@ int dtrace_unregister(dtrace_provider_id_t id)
                                        NULL
                                     };
 
-printk(KERN_INFO "unregister(%p)\n", old);
        if (old->dtpv_pops.dtps_enable ==
            (int (*)(void *, dtrace_id_t, void *))dtrace_enable_nullop) {
                /*
@@ -273,7 +272,6 @@ printk(KERN_INFO "unregister(%p)\n", old);
         * are anonymous probes that are still enabled, we refuse to deregister
         * providers, unless the provider has been invalidated explicitly.
         */
-printk(KERN_INFO "unregister(%p) %d opens\n", old, dtrace_opens);
        if (!old->dtpv_defunct &&
            (dtrace_opens || (dtrace_anon.dta_state != NULL &&
             dtrace_anon.dta_state->dts_necbs > 0))) {
@@ -293,7 +291,6 @@ printk(KERN_INFO "unregister(%p) %d opens\n", old, dtrace_opens);
         */
        st.prov = old;
        err = dtrace_probe_for_each(dtrace_unregister_check, &st);
-printk(KERN_INFO "unregister(%p) check -> %d\n", old, err);
        if (err < 0) {
                if (!self) {
                        mutex_unlock(&dtrace_lock);
@@ -310,7 +307,6 @@ printk(KERN_INFO "unregister(%p) check -> %d\n", old, err);
         * We chain all the probes together for further processing.
         */
        dtrace_probe_for_each(dtrace_unregister_probe, &st);
-printk(KERN_INFO "unregister(%p) unregister_probe done\n", old);
 
        /*
         * The probes associated with the provider have been removed.  Ensure
@@ -326,7 +322,6 @@ printk(KERN_INFO "unregister(%p) unregister_probe done\n", old);
 
                st.first = probe->dtpr_nextmod;
 
-printk(KERN_INFO "unregister(%p) Destroying probe %d\n", old, probe_id);
                old->dtpv_pops.dtps_destroy(old->dtpv_arg, probe_id,
                                            probe->dtpr_arg);
 
index f83870a27e333e35e410ecfda0c3bb01a391aa96..d02224d3361e0998622458e619a611c8c885a8be 100644 (file)
@@ -94,7 +94,6 @@ void dtrace_speculation_commit(dtrace_state_t *state, processorid_t cpu,
        if (which == 0)
                return;
 
-printk(KERN_INFO "spec-commit: CPU#%d, which %d\n", cpu, which);
        if (which > state->dts_nspeculations) {
                cpu_core[cpu].cpuc_dtrace_flags |= CPU_DTRACE_ILLOP;
                return;
@@ -105,7 +104,6 @@ printk(KERN_INFO "spec-commit: CPU#%d, which %d\n", cpu, which);
        dest = &state->dts_buffer[cpu];
 
        do {
-printk(KERN_INFO "spec-commit: a) CPU#%d, which %d, spec-state %d\n", cpu, which, spec->dtsp_state);
                curr = spec->dtsp_state;
 
                if (curr == DTRACESPEC_COMMITTINGMANY)
@@ -152,7 +150,6 @@ printk(KERN_INFO "spec-commit: a) CPU#%d, which %d, spec-state %d\n", cpu, which
                default:
                        ASSERT(0);
                }
-printk(KERN_INFO "spec-commit: a) CPU#%d, which %d, spec-state %d -> %d\n", cpu, which, curr, new);
        } while (cmpxchg((uint32_t *)&spec->dtsp_state, curr, new) !=
                 curr);
 
index 2fdcd285d8ae5f57d927351b417d17fb60b1313c..afbccb4ae7d7941a4b55495419d7e008208ed6b0 100644 (file)
@@ -481,7 +481,6 @@ static int dtrace_state_buffer(dtrace_state_t *state, dtrace_buffer_t *buf,
        ASSERT(state->dts_activity == DTRACE_ACTIVITY_INACTIVE ||
               (state == dtrace_anon.dta_state &&
               state->dts_activity == DTRACE_ACTIVITY_ACTIVE));
-printk(KERN_INFO "state_buffer(%p, %p, %d) opt[%d] = %lld\n", state, buf, which, which, opt[which]);
 
        if (opt[which] == DTRACEOPT_UNSET || opt[which] == 0)
                return 0;
@@ -493,7 +492,6 @@ printk(KERN_INFO "state_buffer(%p, %p, %d) opt[%d] = %lld\n", state, buf, which,
                flags |= DTRACEBUF_NOSWITCH;
 
        if (which == DTRACEOPT_BUFSIZE) {
-printk(KERN_INFO "state_buffer(%p, %p, %d) opt[CPU] = %lld, opt[BUFPOLICY] = %lld, sta_state = %p\n", state, buf, which, opt[DTRACEOPT_CPU], opt[DTRACEOPT_BUFPOLICY], dtrace_anon.dta_state);
                if (opt[DTRACEOPT_BUFPOLICY] == DTRACEOPT_BUFPOLICY_RING)
                        flags |= DTRACEBUF_RING;
 
@@ -503,7 +501,6 @@ printk(KERN_INFO "state_buffer(%p, %p, %d) opt[CPU] = %lld, opt[BUFPOLICY] = %ll
                if (state != dtrace_anon.dta_state ||
                    state->dts_activity != DTRACE_ACTIVITY_ACTIVE)
                        flags |= DTRACEBUF_INACTIVE;
-printk(KERN_INFO "state_buffer(%p, %p, %d) flags = %08x\n", state, buf, which, flags);
        }
 
        for (size = opt[which]; size >= sizeof (uint64_t); size >>= 1) {
@@ -525,7 +522,6 @@ printk(KERN_INFO "state_buffer(%p, %p, %d) flags = %08x\n", state, buf, which, f
                }
 
                rval = dtrace_buffer_alloc(buf, size, flags, cpu);
-printk(KERN_INFO "state_buffer: Alloc %d buffer: tomax %p xamot %p\n", which, buf->dtb_tomax, buf->dtb_xamot);
 
                if (rval != -ENOMEM) {
                        opt[which] = size;
@@ -600,7 +596,6 @@ int dtrace_state_go(dtrace_state_t *state, processorid_t *cpu)
        mutex_lock(&cpu_lock);
        mutex_lock(&dtrace_lock);
 
-printk(KERN_INFO "state_go(1): dts_activity = %d (vs warmup %d or draining %d)\n", state->dts_activity, DTRACE_ACTIVITY_WARMUP, DTRACE_ACTIVITY_DRAINING);
        if (state->dts_activity != DTRACE_ACTIVITY_INACTIVE) {
                rval = -EBUSY;
                goto out;
@@ -633,7 +628,6 @@ printk(KERN_INFO "state_go(1): dts_activity = %d (vs warmup %d or draining %d)\n
        }
 
        spec = kzalloc(nspec * sizeof(dtrace_speculation_t), GFP_KERNEL);
-printk(KERN_INFO "state_go: nspec = %d, spec = %p (%lld bytes)\n", (int)nspec, spec, nspec * sizeof(dtrace_speculation_t));
        if (spec == NULL) {
                rval = -ENOMEM;
                goto out;
@@ -648,7 +642,6 @@ printk(KERN_INFO "state_go: nspec = %d, spec = %p (%lld bytes)\n", (int)nspec, s
                        goto err;
                }
 
-printk(KERN_INFO "state_go: spec[%d].buf = %p (%d bytes)\n", i, buf, bufsize);
                spec[i].dtsp_buffer = buf;
        }
 
@@ -790,7 +783,6 @@ printk(KERN_INFO "state_go: spec[%d].buf = %p (%d bytes)\n", i, buf, bufsize);
        state->dts_deadman = cyclic_add(&hdlr, &when);
 
        state->dts_activity = DTRACE_ACTIVITY_WARMUP;
-printk(KERN_INFO "state_go(2): dts_activity = %d (vs warmup %d or draining %d)\n", state->dts_activity, DTRACE_ACTIVITY_WARMUP, DTRACE_ACTIVITY_DRAINING);
 
        /*
         * Now it's time to actually fire the BEGIN probe.  We need to disable
@@ -811,7 +803,6 @@ printk(KERN_INFO "state_go(2): dts_activity = %d (vs warmup %d or draining %d)\n
         * We may have had an exit action from a BEGIN probe; only change our
         * state to ACTIVE if we're still in WARMUP.
         */
-printk(KERN_INFO "state_go(3): dts_activity = %d (vs warmup %d or draining %d)\n", state->dts_activity, DTRACE_ACTIVITY_WARMUP, DTRACE_ACTIVITY_DRAINING);
        ASSERT(state->dts_activity == DTRACE_ACTIVITY_WARMUP ||
               state->dts_activity == DTRACE_ACTIVITY_DRAINING);
 
@@ -993,7 +984,6 @@ void dtrace_state_destroy(dtrace_state_t *state)
                 * issue a sync to be sure that everyone is out of probe
                 * context before we start blowing away ECBs.
                 */
-printk(KERN_INFO "state_destroy: Setting dts_activity from %d to %d (KILLED)\n", state->dts_activity, DTRACE_ACTIVITY_KILLED);
                state->dts_activity = DTRACE_ACTIVITY_KILLED;
                dtrace_sync();
        }
index 584197c9afa411ad522fd676be74658e4ca2ec1b..e66a77f258cb216dca1c4fd1591eb5918696fb7f 100644 (file)
  */
 
 #include <linux/fs.h>
+#include <linux/ktime.h>
 #include <linux/miscdevice.h>
 #include <linux/slab.h>
+#include <asm/irq_regs.h>
+#include <asm/ptrace.h>
 
 #include "dtrace.h"
 #include "dtrace_dev.h"
@@ -84,8 +87,64 @@ static atomic_t      profile_total;          /* current number of profile probes */
 static void profile_tick(void *arg)
 {
        profile_probe_t *prof = arg;
+       struct pt_regs  *regs = get_irq_regs();
+       unsigned long   pc = 0, upc = 0;
 
-       dtrace_probe(prof->prof_id, 0, 0, 0, 0, 0); /* FIXME */
+       if (user_mode(regs))
+               upc = GET_IP(regs);
+       else
+               pc = GET_IP(regs);
+
+       dtrace_probe(prof->prof_id, pc, upc, 0, 0, 0);
+}
+
+static void profile_prof(void *arg)
+{
+       profile_probe_percpu_t  *pcpu = arg;
+       profile_probe_t         *prof = pcpu->profc_probe;
+       ktime_t                 late;
+       struct pt_regs          *regs = get_irq_regs();
+       unsigned long           pc = 0, upc = 0;
+
+       late = ktime_sub(dtrace_gethrtime(), pcpu->profc_expected);
+       pcpu->profc_expected = ktime_add(pcpu->profc_expected,
+                                        pcpu->profc_interval);
+
+       if (user_mode(regs))
+               upc = GET_IP(regs);
+       else
+               pc = GET_IP(regs);
+
+       dtrace_probe(prof->prof_id, pc, upc, ktime_to_ns(late), 0, 0);
+}
+
+static void profile_online(void *arg, processorid_t cpu, cyc_handler_t *hdlr,
+                          cyc_time_t *when)
+{
+       profile_probe_t         *prof = arg;
+       profile_probe_percpu_t  *pcpu;
+
+       pcpu = kzalloc(sizeof(profile_probe_percpu_t), GFP_KERNEL);
+       pcpu->profc_probe = prof;
+
+       hdlr->cyh_func = profile_prof;
+       hdlr->cyh_arg = pcpu;
+       hdlr->cyh_level = CY_HIGH_LEVEL;
+
+       when->cyt_interval = prof->prof_interval;
+       when->cyt_when = ktime_add(dtrace_gethrtime(), when->cyt_interval);
+
+       pcpu->profc_expected = when->cyt_when;
+       pcpu->profc_interval = when->cyt_interval;
+}
+
+static void profile_offline(void *arg, processorid_t cpu, void *oarg)
+{
+       profile_probe_percpu_t  *pcpu = oarg;
+
+       ASSERT(pcpu->profc_probe == arg);
+
+       kfree(pcpu);
 }
 
 static void profile_create(ktime_t interval, const char *name, int kind)
@@ -262,9 +321,7 @@ void profile_provide(void *arg, const dtrace_probedesc_t *desc)
 int profile_enable(void *arg, dtrace_id_t id, void *parg)
 {
        profile_probe_t         *prof = parg;
-#ifdef FIXME
        cyc_omni_handler_t      omni;
-#endif
        cyc_handler_t           hdlr;
        cyc_time_t              when;
 
@@ -283,16 +340,11 @@ int profile_enable(void *arg, dtrace_id_t id, void *parg)
        } else {
                ASSERT(prof->prof_kind == PROF_PROFILE);        
 
-#ifdef FIXME
                omni.cyo_online = profile_online;
                omni.cyo_offline = profile_offline;
                omni.cyo_arg = prof;
 
                prof->prof_cyclic = cyclic_add_omni(&omni);
-#else
-               prof->prof_cyclic = CYCLIC_NONE;
-               return -ENOTSUPP;
-#endif
        }
 
        return 0;
index 3dab2a42eed25b4c3d169d60276dd887eec8af3e..2af6ff08d1a31f80ea0c9558c32fc70bea5ea0f5 100644 (file)
@@ -69,13 +69,8 @@ void systrace_provide(void *arg, const dtrace_probedesc_t *desc)
                sz = strlen(nm);
                if (sz > 4 && memcmp(nm, "sys_", 4) == 0)
                        nm += 4;
-#if 0
                else if (sz > 5 && memcmp(nm, "stub_", 5) == 0)
                        nm += 5;
-#else
-               else if (sz > 5 && memcmp(nm, "stub_", 5) == 0)
-                       continue;
-#endif
 
                if (dtrace_probe_lookup(syscall_id, NULL, nm, "entry") != 0)
                        continue;
@@ -92,59 +87,65 @@ void systrace_provide(void *arg, const dtrace_probedesc_t *desc)
        }
 }
 
+static dt_sys_call_t get_intercept(int sysnum)
+{
+       switch (sysnum) {
+       default:
+               return systrace_info->syscall;
+       case __NR_clone:
+               return systrace_info->stubs[SCE_CLONE];
+       case __NR_fork:
+               return systrace_info->stubs[SCE_FORK];
+       case __NR_vfork:
+               return systrace_info->stubs[SCE_VFORK];
+       case __NR_sigaltstack:
+               return systrace_info->stubs[SCE_SIGALTSTACK];
+       case __NR_iopl:
+               return systrace_info->stubs[SCE_IOPL];
+       case __NR_execve:
+               return systrace_info->stubs[SCE_EXECVE];
+       case __NR_rt_sigreturn:
+               return systrace_info->stubs[SCE_RT_SIGRETURN];
+       }
+}
+
 int systrace_enable(void *arg, dtrace_id_t id, void *parg)
 {
-       int     sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
-       int     enabled =
+       int             sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
+       int             enabled =
                systrace_info->sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
                systrace_info->sysent[sysnum].stsy_return != DTRACE_IDNONE;
+       dt_sys_call_t   intercept = get_intercept(sysnum);;
 
-#if 0
-       if (SYSTRACE_ISENTRY((uintptr_t)parg))
-               systrace_info->sysent[sysnum].stsy_entry = id;
-       else
-               systrace_info->sysent[sysnum].stsy_return = id;
-
-       if (enabled) {
-               ASSERT((void *)*(systrace_info->sysent[sysnum].stsy_tblent) ==
-                      (void *)systrace_info->syscall);
-
-               return 0;
-       }
-
-       (void)cmpxchg(systrace_info->sysent[sysnum].stsy_tblent,
-                     systrace_info->sysent[sysnum].stsy_underlying,
-                     systrace_info->syscall);
-#else
        if (!enabled) {
                if (cmpxchg(systrace_info->sysent[sysnum].stsy_tblent,
                            systrace_info->sysent[sysnum].stsy_underlying,
-                           systrace_info->syscall) !=
+                           intercept) !=
                    systrace_info->sysent[sysnum].stsy_underlying)
                        return 0;
        } else
                ASSERT((void *)*(systrace_info->sysent[sysnum].stsy_tblent) ==
-                      (void *)systrace_info->syscall);
+                      (void *)intercept);
 
        if (SYSTRACE_ISENTRY((uintptr_t)parg))
                systrace_info->sysent[sysnum].stsy_entry = id;
        else
                systrace_info->sysent[sysnum].stsy_return = id;
-#endif
 
        return 0;
 }
 
 void systrace_disable(void *arg, dtrace_id_t id, void *parg)
 {
-       int     sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
-       int     enabled =
+       int             sysnum = SYSTRACE_SYSNUM((uintptr_t)parg);
+       int             enabled =
                systrace_info->sysent[sysnum].stsy_entry != DTRACE_IDNONE ||
                systrace_info->sysent[sysnum].stsy_return != DTRACE_IDNONE;
+       dt_sys_call_t   intercept = get_intercept(sysnum);;
 
        if (enabled)
                (void)cmpxchg(systrace_info->sysent[sysnum].stsy_tblent,
-                             systrace_info->syscall,
+                             intercept,
                              systrace_info->sysent[sysnum].stsy_underlying);
 
        if (SYSTRACE_ISENTRY((uintptr_t)parg))