/**
 * @brief Stores the data collected from a "/proc/meminfo"
 *
 * @param dpg Struct that polled data is added to.
 * @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
 * @return DTOP_POLL_OK - Poll of dpg successful.
 */
int dtop_meminfo_poll(struct dtop_data_point_gatherer *dpg)
{
	char *data;
	int *line_len = malloc(sizeof(int) *
			((struct dtop_meminfo_vars *)
			(dpg->priv))->line_count);
	int read;
	struct dt_procdict dict;
	int i, j, n, sum;

	read = dt_read_file(dpg->file, &data, DTOP_MEM_SIZE);
	if (read == 0 || data == 0)
		return DTOP_POLL_IO_ERR;

	sum = 0;
	/* Assigns each line read from the file, a length */
	for (n = 0; n < ((struct dtop_meminfo_vars *)
				(dpg->priv))->line_count; n++) {
		line_len[n] = dt_read_line(((struct dtop_meminfo_vars *)
					(dpg->priv))->line[n],
					   DTOP_MEM_LINE, data,
					   DTOP_MEM_SIZE, sum);
		if (n <= (((struct dtop_meminfo_vars *)
			(dpg->priv))->line_count - 1)) {
			sum += (line_len[n] + 1);
		}

	}

	/* Stores dp names and values in dictionary */
	for (i = 0; i < dpg->data_points_len; i++)
		dt_meminfo_parse(((struct dtop_meminfo_vars *)
			(dpg->priv))->line[i], line_len[i], i, &dict);

	/* Assigns the dp value to the dp struct */
	for (j = 0; j < dpg->data_points_len; j++) {
		i = dt_find_dict_idx(dpg->data_points[j].name, &dict);
		if (i >= 0 && i < dict.max) {
			sscanf(dict.val[i], "%" PRIu64,
			       &(dpg->data_points[i].data.d_ulong));
			dpg->data_points[i].data.d_ulong *= 1024;
			if (dpg->data_points[i].
				initial_data_populated == NOT_POPULATED) {
				dpg->data_points[i].initial_data.d_ulong
					= dpg->data_points[i].data.d_ulong;
				dpg->data_points[i].initial_data_populated
					= POPULATED;
			}
		}
	}

	dt_free(&data);
	free(line_len);
	return DTOP_POLL_OK;
}
Beispiel #2
0
void
dt_dof_fini(dtrace_hdl_t *dtp)
{
	dt_dof_t *ddo = &dtp->dt_dof;

	dt_free(dtp, ddo->ddo_xlimport);
	dt_free(dtp, ddo->ddo_xlexport);

	dt_buf_destroy(dtp, &ddo->ddo_secs);
	dt_buf_destroy(dtp, &ddo->ddo_strs);
	dt_buf_destroy(dtp, &ddo->ddo_ldata);
	dt_buf_destroy(dtp, &ddo->ddo_udata);

	dt_buf_destroy(dtp, &ddo->ddo_probes);
	dt_buf_destroy(dtp, &ddo->ddo_args);
	dt_buf_destroy(dtp, &ddo->ddo_offs);
	dt_buf_destroy(dtp, &ddo->ddo_enoffs);
	dt_buf_destroy(dtp, &ddo->ddo_rels);

	dt_buf_destroy(dtp, &ddo->ddo_xlms);
}
Beispiel #3
0
void *
dtrace_getopt_dof(dtrace_hdl_t *dtp)
{
	dof_hdr_t *dof;
	dof_sec_t *sec;
	dof_optdesc_t *dofo;
	int i, nopts = 0, len = sizeof (dof_hdr_t) +
	    roundup(sizeof (dof_sec_t), sizeof (uint64_t));

	for (i = 0; i < DTRACEOPT_MAX; i++) {
		if (dtp->dt_options[i] != DTRACEOPT_UNSET)
			nopts++;
	}

	len += sizeof (dof_optdesc_t) * nopts;

	if ((dof = dt_zalloc(dtp, len)) == NULL ||
	    dof_hdr(dtp, DOF_VERSION, dof) != 0) {
		dt_free(dtp, dof);
		return (NULL);
	}

	dof->dofh_secnum = 1;	/* only DOF_SECT_OPTDESC */
	dof->dofh_loadsz = len;
	dof->dofh_filesz = len;

	/*
	 * Fill in the option section header...
	 */
	sec = (dof_sec_t *)((uintptr_t)dof + sizeof (dof_hdr_t));
	sec->dofs_type = DOF_SECT_OPTDESC;
	sec->dofs_align = sizeof (uint64_t);
	sec->dofs_flags = DOF_SECF_LOAD;
	sec->dofs_entsize = sizeof (dof_optdesc_t);

	dofo = (dof_optdesc_t *)((uintptr_t)sec +
	    roundup(sizeof (dof_sec_t), sizeof (uint64_t)));

	sec->dofs_offset = (uintptr_t)dofo - (uintptr_t)dof;
	sec->dofs_size = sizeof (dof_optdesc_t) * nopts;

	for (i = 0; i < DTRACEOPT_MAX; i++) {
		if (dtp->dt_options[i] == DTRACEOPT_UNSET)
			continue;

		dofo->dofo_option = i;
		dofo->dofo_strtab = DOF_SECIDX_NONE;
		dofo->dofo_value = dtp->dt_options[i];
		dofo++;
	}

	return (dof);
}
/**
 * @brief Scans "/proc/meminfo in order to autodetect dps.
 *
 * Searches through "/proc/meminfo" file for all available data
 * points to create as dp structs.
 *
 * @param storage dtop_meminfo_vars struct where relevant variables are stored.
 */
int dtop_meminfo_search(struct dtop_meminfo_vars *storage)
{
	int i, k, n, sum;
	char *data;
	int *line_len = malloc(sizeof(int) * storage->line_count);
	int read;
	struct dt_procdict dict;
	struct dtop_data_point *data_points;

	storage->line = malloc(storage->line_count * sizeof(*storage->line));

	for (i = 0; i < storage->line_count; i++)
		storage->line[i] = malloc(sizeof(char) * DTOP_MEM_LINE);

	read = dt_read_file("/proc/meminfo", &data, DTOP_MEM_SIZE);
	if (read == 0 || data == 0)
		return DTOP_POLL_IO_ERR;

	sum = 0;
	/* Assigns each line read from the file, a length */
	for (n = 0; n < storage->line_count; n++) {
		line_len[n] = dt_read_line(storage->line[n],
					   DTOP_MEM_LINE, data,
					   DTOP_MEM_SIZE, sum);
		if (n < (storage->line_count - 1))
			sum += (line_len[n] + 1);
	}

	/* Stores dp names in dictionary */
	for (i = 0; i < (storage->line_count); i++)
		dt_parse_proc_same_line_key_and_val(storage->line[i],
						line_len[i], i, &dict);

	data_points = malloc
		       (storage->line_count * sizeof(struct dtop_data_point));

	k = 0;
	/* Creates a dtop_data_point struct for each dp found in the file */
	for (i = 0; i < dict.max; i++) {
		data_points[i].name = dict.key[i];
		data_points[i].prefix = NULL;
		data_points[i].type = DTOP_ULONG;
		k++;
	}

	/* Calls dpg constructor, dpg will point to the dp struct */
	construct_meminfo_file_dpg(data_points, storage);

	free(line_len);
	dt_free(&data);

	return DTOP_POLL_OK;
}
Beispiel #5
0
void
dt_proc_hash_destroy(dtrace_hdl_t *dtp)
{
	dt_proc_hash_t *dph = dtp->dt_procs;
	dt_proc_t *dpr;

	while ((dpr = dt_list_next(&dph->dph_lrulist)) != NULL)
		dt_proc_destroy(dtp, dpr->dpr_proc);

	dtp->dt_procs = NULL;
	dt_free(dtp, dph);
}
Beispiel #6
0
static int
dt_dof_reset(dtrace_hdl_t *dtp, dtrace_prog_t *pgp)
{
	dt_dof_t *ddo = &dtp->dt_dof;
	uint_t i, nx = dtp->dt_xlatorid;

	assert(ddo->ddo_hdl == dtp);
	ddo->ddo_pgp = pgp;

	ddo->ddo_nsecs = 0;
	ddo->ddo_strsec = DOF_SECIDX_NONE;

	dt_free(dtp, ddo->ddo_xlimport);
	dt_free(dtp, ddo->ddo_xlexport);

	ddo->ddo_xlimport = dt_alloc(dtp, sizeof (dof_secidx_t) * nx);
	ddo->ddo_xlexport = dt_alloc(dtp, sizeof (dof_secidx_t) * nx);

	if (nx != 0 && (ddo->ddo_xlimport == NULL || ddo->ddo_xlexport == NULL))
		return (-1); /* errno is set for us */

	for (i = 0; i < nx; i++) {
		ddo->ddo_xlimport[i] = DOF_SECIDX_NONE;
		ddo->ddo_xlexport[i] = DOF_SECIDX_NONE;
	}

	dt_buf_reset(dtp, &ddo->ddo_secs);
	dt_buf_reset(dtp, &ddo->ddo_strs);
	dt_buf_reset(dtp, &ddo->ddo_ldata);
	dt_buf_reset(dtp, &ddo->ddo_udata);

	dt_buf_reset(dtp, &ddo->ddo_probes);
	dt_buf_reset(dtp, &ddo->ddo_args);
	dt_buf_reset(dtp, &ddo->ddo_offs);
	dt_buf_reset(dtp, &ddo->ddo_enoffs);
	dt_buf_reset(dtp, &ddo->ddo_rels);

	dt_buf_reset(dtp, &ddo->ddo_xlms);
	return (0);
}
Beispiel #7
0
void *
dt_buf_claim(dtrace_hdl_t *dtp, dt_buf_t *bp)
{
	void *buf = bp->dbu_buf;

	if (bp->dbu_err != 0) {
		dt_free(dtp, buf);
		buf = NULL;
	}

	bp->dbu_buf = bp->dbu_ptr = NULL;
	bp->dbu_len = 0;

	return (buf);
}
Beispiel #8
0
Datei: dt.c Projekt: Govelius/dmd
void dt_optimize(dt_t *dt)
{   dt_t *dtn;

    if (dt)
    {   for (; 1; dt = dtn)
        {
            dtn = dt->DTnext;
            if (!dtn)
                break;
            switch (dt->dt)
            {
            case DT_azeros:
                if (dtn->dt == DT_1byte && dtn->DTonebyte == 0)
                {
                    dt->DTazeros += 1;
                    goto L1;
                }
                else if (dtn->dt == DT_azeros)
                {
                    dt->DTazeros += dtn->DTazeros;
                    goto L1;
                }
                break;

            case DT_1byte:
                if (dt->DTonebyte == 0)
                {
                    if (dtn->dt == DT_1byte && dtn->DTonebyte == 0)
                    {
                        dt->DTazeros = 2;
                        goto L1;
                    }
                    else if (dtn->dt == DT_azeros)
                    {
                        dt->DTazeros = 1 + dtn->DTazeros;
L1:
                        dt->dt = DT_azeros;
                        dt->DTnext = dtn->DTnext;
                        dtn->DTnext = NULL;
                        dt_free(dtn);
                        dtn = dt;
                    }
                }
                break;
            }
        }
    }
}
Beispiel #9
0
/*PRINTFLIKE3*/
static struct ps_prochandle *
dt_proc_error(dtrace_hdl_t *dtp, dt_proc_t *dpr, const char *format, ...)
{
	va_list ap;

	va_start(ap, format);
	dt_set_errmsg(dtp, NULL, NULL, NULL, 0, format, ap);
	va_end(ap);

	if (dpr->dpr_proc != NULL)
		Prelease(dpr->dpr_proc, 0);

	dt_free(dtp, dpr);
	(void) dt_set_errno(dtp, EDT_COMPILER);
	return (NULL);
}
Beispiel #10
0
static void
dt_proc_bpdestroy(dt_proc_t *dpr, int delbkpts)
{
	int state = Pstate(dpr->dpr_proc);
	dt_bkpt_t *dbp, *nbp;

	assert(DT_MUTEX_HELD(&dpr->dpr_lock));

	for (dbp = dt_list_next(&dpr->dpr_bps); dbp != NULL; dbp = nbp) {
		if (delbkpts && dbp->dbp_active &&
		    state != PS_LOST && state != PS_UNDEAD) {
			(void) Pdelbkpt(dpr->dpr_proc,
			    dbp->dbp_addr, dbp->dbp_instr);
		}
		nbp = dt_list_next(dbp);
		dt_list_delete(&dpr->dpr_bps, dbp);
		dt_free(dpr->dpr_hdl, dbp);
	}
}
Beispiel #11
0
dt_inttab_t *
dt_inttab_create(dtrace_hdl_t *dtp)
{
	uint_t len = _dtrace_intbuckets;
	dt_inttab_t *ip;

	assert((len & (len - 1)) == 0);

	if ((ip = dt_zalloc(dtp, sizeof (dt_inttab_t))) == NULL ||
	    (ip->int_hash = dt_zalloc(dtp, sizeof (void *) * len)) == NULL) {
		dt_free(dtp, ip);
		return (NULL);
	}

	ip->int_hdl = dtp;
	ip->int_hashlen = len;

	return (ip);
}
Beispiel #12
0
void
dt_buf_write(dtrace_hdl_t *dtp, dt_buf_t *bp,
    const void *buf, size_t len, size_t align)
{
	size_t off = (size_t)(bp->dbu_ptr - bp->dbu_buf);
	size_t adj = roundup(off, align) - off;

	if (bp->dbu_err != 0) {
		(void) dt_set_errno(dtp, bp->dbu_err);
		return; /* write silently fails */
	}

	if (bp->dbu_ptr + adj + len > bp->dbu_buf + bp->dbu_len) {
		size_t new_len = bp->dbu_len * 2;
		uchar_t *new_buf;
		uint_t r = 1;

		while (bp->dbu_ptr + adj + len > bp->dbu_buf + new_len) {
			new_len *= 2;
			r++;
		}

		if ((new_buf = dt_zalloc(dtp, new_len)) == NULL) {
			bp->dbu_err = dtrace_errno(dtp);
			return;
		}

		bcopy(bp->dbu_buf, new_buf, off);
		dt_free(dtp, bp->dbu_buf);

		bp->dbu_buf = new_buf;
		bp->dbu_ptr = new_buf + off;
		bp->dbu_len = new_len;
		bp->dbu_resizes += r;
	}

	bp->dbu_ptr += adj;
	bcopy(buf, bp->dbu_ptr, len);
	bp->dbu_ptr += len;
}
Beispiel #13
0
/*ARGSUSED*/
static int
dt_opt_preallocate(dtrace_hdl_t *dtp, const char *arg, uintptr_t option)
{
	dtrace_optval_t size;
	void *p;

	if (arg == NULL || dt_optval_parse(arg, &size) != 0)
		return (dt_set_errno(dtp, EDT_BADOPTVAL));

	if (size > SIZE_MAX)
		size = SIZE_MAX;

	if ((p = dt_zalloc(dtp, size)) == NULL) {
		do {
			size /= 2;
		} while ((p = dt_zalloc(dtp, size)) == NULL);
	}

	dt_free(dtp, p);

	return (0);
}
Beispiel #14
0
/*************************
 * Finish and return completed data structure.
 */
dt_t *DtBuilder::finish()
{
    /* Merge all the 0s at the start of the list
     * so we can later check for dtallzeros()
     */
    if (head && head->dt == DT_azeros)
    {
        while (1)
        {
            dt_t *dtn = head->DTnext;
            if (!(dtn && dtn->dt == DT_azeros))
                break;

            // combine head and dtn
            head->DTazeros += dtn->DTazeros;
            head->DTnext = dtn->DTnext;
            dtn->DTnext = NULL;
            dt_free(dtn);
        }
    }

    return head;
}
Beispiel #15
0
/*
 * Create a new priority queue.
 *
 * size is the maximum number of items that will be stored in the priority
 * queue at one time.
 */
dt_pq_t *
dt_pq_init(dtrace_hdl_t *dtp, uint_t size, dt_pq_value_f value_cb, void *cb_arg)
{
	dt_pq_t *p;
	assert(size > 1);

	if ((p = dt_zalloc(dtp, sizeof (dt_pq_t))) == NULL)
		return (NULL);

	p->dtpq_items = dt_zalloc(dtp, size * sizeof (p->dtpq_items[0]));
	if (p->dtpq_items == NULL) {
		dt_free(dtp, p);
		return (NULL);
	}

	p->dtpq_hdl = dtp;
	p->dtpq_size = size;
	p->dtpq_last = 1;
	p->dtpq_value = value_cb;
	p->dtpq_arg = cb_arg;

	return (p);
}
Beispiel #16
0
Datei: dt.c Projekt: TheDharc/dmd
void dt_optimize(dt_t *dt)
{   dt_t *dtn;

    if (dt)
    {   for (; 1; dt = dtn)
        {
            dtn = dt->DTnext;
            if (!dtn)
                break;
            if (dt->dt == DT_azeros)
            {
                if (dtn->dt == DT_azeros)
                {
                    dt->DTazeros += dtn->DTazeros;
                    dt->dt = DT_azeros;
                    dt->DTnext = dtn->DTnext;
                    dtn->DTnext = NULL;
                    dt_free(dtn);
                    dtn = dt;
                }
            }
        }
    }
}
Beispiel #17
0
int
dt_provider_xref(dtrace_hdl_t *dtp, dt_provider_t *pvp, id_t id)
{
	size_t oldsize = BT_SIZEOFMAP(pvp->pv_xrmax);
	size_t newsize = BT_SIZEOFMAP(dtp->dt_xlatorid);

	assert(id >= 0 && id < dtp->dt_xlatorid);

	if (newsize > oldsize) {
		ulong_t *xrefs = dt_zalloc(dtp, newsize);

		if (xrefs == NULL)
			return (-1);

		bcopy(pvp->pv_xrefs, xrefs, oldsize);
		dt_free(dtp, pvp->pv_xrefs);

		pvp->pv_xrefs = xrefs;
		pvp->pv_xrmax = dtp->dt_xlatorid;
	}

	BT_SET(pvp->pv_xrefs, id);
	return (0);
}
Beispiel #18
0
static int
dt_pid_per_sym(dt_pid_probe_t *pp, const GElf_Sym *symp, const char *func)
{
	dtrace_hdl_t *dtp = pp->dpp_dtp;
	dt_pcb_t *pcb = pp->dpp_pcb;
	dt_proc_t *dpr = pp->dpp_dpr;
	fasttrap_probe_spec_t *ftp;
	uint64_t off;
	char *end;
	uint_t nmatches = 0;
	ulong_t sz;
	int glob, err;
	int isdash = strcmp("-", func) == 0;
	pid_t pid;

#if defined(sun)
	pid = Pstatus(pp->dpp_pr)->pr_pid;
#else
	pid = proc_getpid(pp->dpp_pr);
#endif

	dt_dprintf("creating probe pid%d:%s:%s:%s\n", (int)pid, pp->dpp_obj,
	    func, pp->dpp_name);

	sz = sizeof (fasttrap_probe_spec_t) + (isdash ? 4 :
	    (symp->st_size - 1) * sizeof (ftp->ftps_offs[0]));

	if ((ftp = dt_alloc(dtp, sz)) == NULL) {
		dt_dprintf("proc_per_sym: dt_alloc(%lu) failed\n", sz);
		return (1); /* errno is set for us */
	}

	ftp->ftps_pid = pid;
	(void) strncpy(ftp->ftps_func, func, sizeof (ftp->ftps_func));

	dt_pid_objname(ftp->ftps_mod, sizeof (ftp->ftps_mod), pp->dpp_lmid,
	    pp->dpp_obj);

	if (!isdash && gmatch("return", pp->dpp_name)) {
		if (dt_pid_create_return_probe(pp->dpp_pr, dtp, ftp, symp,
		    pp->dpp_stret) < 0) {
			return (dt_pid_error(dtp, pcb, dpr, ftp,
			    D_PROC_CREATEFAIL, "failed to create return probe "
			    "for '%s': %s", func,
			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
		}

		nmatches++;
	}

	if (!isdash && gmatch("entry", pp->dpp_name)) {
		if (dt_pid_create_entry_probe(pp->dpp_pr, dtp, ftp, symp) < 0) {
			return (dt_pid_error(dtp, pcb, dpr, ftp,
			    D_PROC_CREATEFAIL, "failed to create entry probe "
			    "for '%s': %s", func,
			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
		}

		nmatches++;
	}

	glob = strisglob(pp->dpp_name);
	if (!glob && nmatches == 0) {
		off = strtoull(pp->dpp_name, &end, 16);
		if (*end != '\0') {
			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_NAME,
			    "'%s' is an invalid probe name", pp->dpp_name));
		}

		if (off >= symp->st_size) {
			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_OFF,
			    "offset 0x%llx outside of function '%s'",
			    (u_longlong_t)off, func));
		}

		err = dt_pid_create_offset_probe(pp->dpp_pr, pp->dpp_dtp, ftp,
		    symp, off);

		if (err == DT_PROC_ERR) {
			return (dt_pid_error(dtp, pcb, dpr, ftp,
			    D_PROC_CREATEFAIL, "failed to create probe at "
			    "'%s+0x%llx': %s", func, (u_longlong_t)off,
			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
		}

		if (err == DT_PROC_ALIGN) {
			return (dt_pid_error(dtp, pcb, dpr, ftp, D_PROC_ALIGN,
			    "offset 0x%llx is not aligned on an instruction",
			    (u_longlong_t)off));
		}

		nmatches++;

	} else if (glob && !isdash) {
		if (dt_pid_create_glob_offset_probes(pp->dpp_pr,
		    pp->dpp_dtp, ftp, symp, pp->dpp_name) < 0) {
			return (dt_pid_error(dtp, pcb, dpr, ftp,
			    D_PROC_CREATEFAIL,
			    "failed to create offset probes in '%s': %s", func,
			    dtrace_errmsg(dtp, dtrace_errno(dtp))));
		}

		nmatches++;
	}

	pp->dpp_nmatches += nmatches;

	dt_free(dtp, ftp);

	return (0);
}
Beispiel #19
0
dtrace_difo_t *
dt_as(dt_pcb_t *pcb)
{
	dtrace_hdl_t *dtp = pcb->pcb_hdl;
	dt_irlist_t *dlp = &pcb->pcb_ir;
	uint_t *labels = NULL;
	dt_irnode_t *dip;
	dtrace_difo_t *dp;
	dt_ident_t *idp;

	size_t n = 0;
	uint_t i;

	uint_t kmask, kbits, umask, ubits;
	uint_t krel = 0, urel = 0, xlrefs = 0;

	/*
	 * Select bitmasks based upon the desired symbol linking policy.  We
	 * test (di_extern->di_flags & xmask) == xbits to determine if the
	 * symbol should have a relocation entry generated in the loop below.
	 *
	 * DT_LINK_KERNEL = kernel symbols static, user symbols dynamic
	 * DT_LINK_PRIMARY = primary kernel symbols static, others dynamic
	 * DT_LINK_DYNAMIC = all symbols dynamic
	 * DT_LINK_STATIC = all symbols static
	 *
	 * By 'static' we mean that we use the symbol's value at compile-time
	 * in the final DIF.  By 'dynamic' we mean that we create a relocation
	 * table entry for the symbol's value so it can be relocated later.
	 */
	switch (dtp->dt_linkmode) {
	case DT_LINK_KERNEL:
		kmask = 0;
		kbits = -1u;
		umask = DT_IDFLG_USER;
		ubits = DT_IDFLG_USER;
		break;
	case DT_LINK_PRIMARY:
		kmask = DT_IDFLG_USER | DT_IDFLG_PRIM;
		kbits = 0;
		umask = DT_IDFLG_USER;
		ubits = DT_IDFLG_USER;
		break;
	case DT_LINK_DYNAMIC:
		kmask = DT_IDFLG_USER;
		kbits = 0;
		umask = DT_IDFLG_USER;
		ubits = DT_IDFLG_USER;
		break;
	case DT_LINK_STATIC:
		kmask = umask = 0;
		kbits = ubits = -1u;
		break;
	default:
		xyerror(D_UNKNOWN, "internal error -- invalid link mode %u\n",
		    dtp->dt_linkmode);
	}

	assert(pcb->pcb_difo == NULL);
	pcb->pcb_difo = dt_zalloc(dtp, sizeof (dtrace_difo_t));

	if ((dp = pcb->pcb_difo) == NULL)
		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

	dp->dtdo_buf = dt_alloc(dtp, sizeof (dif_instr_t) * dlp->dl_len);

	if (dp->dtdo_buf == NULL)
		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

	if ((labels = dt_alloc(dtp, sizeof (uint_t) * dlp->dl_label)) == NULL)
		longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

	/*
	 * Make an initial pass through the instruction list, filling in the
	 * instruction buffer with valid instructions and skipping labeled nops.
	 * While doing this, we also fill in our labels[] translation table
	 * and we count up the number of relocation table entries we will need.
	 */
	for (i = 0, dip = dlp->dl_list; dip != NULL; dip = dip->di_next) {
		if (dip->di_label != DT_LBL_NONE)
			labels[dip->di_label] = i;

		if (dip->di_label == DT_LBL_NONE ||
		    dip->di_instr != DIF_INSTR_NOP)
			dp->dtdo_buf[i++] = dip->di_instr;

		if (dip->di_extern == NULL)
			continue; /* no external references needed */

		switch (DIF_INSTR_OP(dip->di_instr)) {
		case DIF_OP_SETX:
			idp = dip->di_extern;
			if ((idp->di_flags & kmask) == kbits)
				krel++;
			else if ((idp->di_flags & umask) == ubits)
				urel++;
			break;
		case DIF_OP_XLATE:
		case DIF_OP_XLARG:
			xlrefs++;
			break;
		default:
			xyerror(D_UNKNOWN, "unexpected assembler relocation "
			    "for opcode 0x%x\n", DIF_INSTR_OP(dip->di_instr));
		}
	}

	assert(i == dlp->dl_len);
	dp->dtdo_len = dlp->dl_len;

	/*
	 * Make a second pass through the instructions, relocating each branch
	 * label to the index of the final instruction in the buffer and noting
	 * any other instruction-specific DIFO flags such as dtdo_destructive.
	 */
	for (i = 0; i < dp->dtdo_len; i++) {
		dif_instr_t instr = dp->dtdo_buf[i];
		uint_t op = DIF_INSTR_OP(instr);

		if (op == DIF_OP_CALL) {
			if (DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUT ||
			    DIF_INSTR_SUBR(instr) == DIF_SUBR_COPYOUTSTR)
				dp->dtdo_destructive = 1;
			continue;
		}

		if (op >= DIF_OP_BA && op <= DIF_OP_BLEU) {
			assert(DIF_INSTR_LABEL(instr) < dlp->dl_label);
			dp->dtdo_buf[i] = DIF_INSTR_BRANCH(op,
			    labels[DIF_INSTR_LABEL(instr)]);
		}
	}

	dt_free(dtp, labels);
	pcb->pcb_asvidx = 0;

	/*
	 * Allocate memory for the appropriate number of variable records and
	 * then fill in each variable record.  As we populate the variable
	 * table we insert the corresponding variable names into the strtab.
	 */
	(void) dt_idhash_iter(dtp->dt_tls, dt_countvar, &n);
	(void) dt_idhash_iter(dtp->dt_globals, dt_countvar, &n);
	(void) dt_idhash_iter(pcb->pcb_locals, dt_countvar, &n);

	if (n != 0) {
		dp->dtdo_vartab = dt_alloc(dtp, n * sizeof (dtrace_difv_t));
		dp->dtdo_varlen = (uint32_t)n;

		if (dp->dtdo_vartab == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

		(void) dt_idhash_iter(dtp->dt_tls, dt_copyvar, pcb);
		(void) dt_idhash_iter(dtp->dt_globals, dt_copyvar, pcb);
		(void) dt_idhash_iter(pcb->pcb_locals, dt_copyvar, pcb);
	}

	/*
	 * Allocate memory for the appropriate number of relocation table
	 * entries based upon our kernel and user counts from the first pass.
	 */
	if (krel != 0) {
		dp->dtdo_kreltab = dt_alloc(dtp,
		    krel * sizeof (dof_relodesc_t));
		dp->dtdo_krelen = krel;

		if (dp->dtdo_kreltab == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
	}

	if (urel != 0) {
		dp->dtdo_ureltab = dt_alloc(dtp,
		    urel * sizeof (dof_relodesc_t));
		dp->dtdo_urelen = urel;

		if (dp->dtdo_ureltab == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
	}

	if (xlrefs != 0) {
		dp->dtdo_xlmtab = dt_zalloc(dtp, sizeof (dt_node_t *) * xlrefs);
		dp->dtdo_xlmlen = xlrefs;

		if (dp->dtdo_xlmtab == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
	}

	/*
	 * If any relocations are needed, make another pass through the
	 * instruction list and fill in the relocation table entries.
	 */
	if (krel + urel + xlrefs != 0) {
		uint_t knodef = pcb->pcb_cflags & DTRACE_C_KNODEF;
		uint_t unodef = pcb->pcb_cflags & DTRACE_C_UNODEF;

		dof_relodesc_t *krp = dp->dtdo_kreltab;
		dof_relodesc_t *urp = dp->dtdo_ureltab;
		dt_node_t **xlp = dp->dtdo_xlmtab;

		i = 0; /* dtdo_buf[] index */

		for (dip = dlp->dl_list; dip != NULL; dip = dip->di_next) {
			dof_relodesc_t *rp;
			ssize_t soff;
			uint_t nodef;

			if (dip->di_label != DT_LBL_NONE &&
			    dip->di_instr == DIF_INSTR_NOP)
				continue; /* skip label declarations */

			i++; /* advance dtdo_buf[] index */

			if (DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLATE ||
			    DIF_INSTR_OP(dip->di_instr) == DIF_OP_XLARG) {
				assert(dp->dtdo_buf[i - 1] == dip->di_instr);
				dt_as_xlate(pcb, dp, i - 1, (uint_t)
				    (xlp++ - dp->dtdo_xlmtab), dip->di_extern);
				continue;
			}

			if ((idp = dip->di_extern) == NULL)
				continue; /* no relocation entry needed */

			if ((idp->di_flags & kmask) == kbits) {
				nodef = knodef;
				rp = krp++;
			} else if ((idp->di_flags & umask) == ubits) {
				nodef = unodef;
				rp = urp++;
			} else
				continue;

			if (!nodef)
				dt_as_undef(idp, i);

			assert(DIF_INSTR_OP(dip->di_instr) == DIF_OP_SETX);
			soff = dt_strtab_insert(pcb->pcb_strtab, idp->di_name);

			if (soff == -1L)
				longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);
			if (soff > DIF_STROFF_MAX)
				longjmp(pcb->pcb_jmpbuf, EDT_STR2BIG);

			rp->dofr_name = (dof_stridx_t)soff;
			rp->dofr_type = DOF_RELO_SETX;
			rp->dofr_offset = DIF_INSTR_INTEGER(dip->di_instr) *
			    sizeof (uint64_t);
			rp->dofr_data = 0;
		}

		assert(krp == dp->dtdo_kreltab + dp->dtdo_krelen);
		assert(urp == dp->dtdo_ureltab + dp->dtdo_urelen);
		assert(xlp == dp->dtdo_xlmtab + dp->dtdo_xlmlen);
		assert(i == dp->dtdo_len);
	}

	/*
	 * Allocate memory for the compiled string table and then copy the
	 * chunks from the string table into the final string buffer.
	 */
	if ((n = dt_strtab_size(pcb->pcb_strtab)) != 0) {
		if ((dp->dtdo_strtab = dt_alloc(dtp, n)) == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

		(void) dt_strtab_write(pcb->pcb_strtab,
		    (dt_strtab_write_f *)dt_copystr, pcb);
		dp->dtdo_strlen = (uint32_t)n;
	}

	/*
	 * Allocate memory for the compiled integer table and then copy the
	 * integer constants from the table into the final integer buffer.
	 */
	if ((n = dt_inttab_size(pcb->pcb_inttab)) != 0) {
		if ((dp->dtdo_inttab = dt_alloc(dtp,
		    n * sizeof (uint64_t))) == NULL)
			longjmp(pcb->pcb_jmpbuf, EDT_NOMEM);

		dt_inttab_write(pcb->pcb_inttab, dp->dtdo_inttab);
		dp->dtdo_intlen = (uint32_t)n;
	}

	/*
	 * Fill in the DIFO return type from the type associated with the
	 * node saved in pcb_dret, and then clear pcb_difo and pcb_dret
	 * now that the assembler has completed successfully.
	 */
	dt_node_diftype(dtp, pcb->pcb_dret, &dp->dtdo_rtype);
	pcb->pcb_difo = NULL;
	pcb->pcb_dret = NULL;

	if (pcb->pcb_cflags & DTRACE_C_DIFV)
		dt_dis(dp, stderr);

	return (dp);
}
Beispiel #20
0
/*
 * Pop the topmost PCB from the PCB stack and destroy any data structures that
 * are associated with it.  If 'err' is non-zero, destroy any intermediate
 * state that is left behind as part of a compilation that has failed.
 */
void
dt_pcb_pop(dtrace_hdl_t *dtp, int err)
{
	dt_pcb_t *pcb = yypcb;
	uint_t i;

	assert(pcb != NULL);
	assert(pcb == dtp->dt_pcb);

	while (pcb->pcb_dstack.ds_next != NULL)
		(void) dt_scope_pop();

	dt_scope_destroy(&pcb->pcb_dstack);
	dt_irlist_destroy(&pcb->pcb_ir);

	dt_node_link_free(&pcb->pcb_list);
	dt_node_link_free(&pcb->pcb_hold);

	if (err != 0) {
		dt_xlator_t *dxp, *nxp;
		dt_provider_t *pvp, *nvp;

		if (pcb->pcb_prog != NULL)
			dt_program_destroy(dtp, pcb->pcb_prog);
		if (pcb->pcb_stmt != NULL)
			dtrace_stmt_destroy(dtp, pcb->pcb_stmt);
		if (pcb->pcb_ecbdesc != NULL)
			dt_ecbdesc_release(dtp, pcb->pcb_ecbdesc);

		for (dxp = dt_list_next(&dtp->dt_xlators); dxp; dxp = nxp) {
			nxp = dt_list_next(dxp);
			if (dxp->dx_gen == dtp->dt_gen)
				dt_xlator_destroy(dtp, dxp);
		}

		for (pvp = dt_list_next(&dtp->dt_provlist); pvp; pvp = nvp) {
			nvp = dt_list_next(pvp);
			if (pvp->pv_gen == dtp->dt_gen)
				dt_provider_destroy(dtp, pvp);
		}

		(void) dt_idhash_iter(dtp->dt_aggs, dt_pcb_pop_ident, dtp);
		dt_idhash_update(dtp->dt_aggs);

		(void) dt_idhash_iter(dtp->dt_globals, dt_pcb_pop_ident, dtp);
		dt_idhash_update(dtp->dt_globals);

		(void) dt_idhash_iter(dtp->dt_tls, dt_pcb_pop_ident, dtp);
		dt_idhash_update(dtp->dt_tls);

		(void) ctf_discard(dtp->dt_cdefs->dm_ctfp);
		(void) ctf_discard(dtp->dt_ddefs->dm_ctfp);
	}

	if (pcb->pcb_pragmas != NULL)
		dt_idhash_destroy(pcb->pcb_pragmas);
	if (pcb->pcb_locals != NULL)
		dt_idhash_destroy(pcb->pcb_locals);
	if (pcb->pcb_idents != NULL)
		dt_idhash_destroy(pcb->pcb_idents);
	if (pcb->pcb_inttab != NULL)
		dt_inttab_destroy(pcb->pcb_inttab);
	if (pcb->pcb_strtab != NULL)
		dt_strtab_destroy(pcb->pcb_strtab);
	if (pcb->pcb_regs != NULL)
		dt_regset_destroy(pcb->pcb_regs);

	for (i = 0; i < pcb->pcb_asxreflen; i++)
		dt_free(dtp, pcb->pcb_asxrefs[i]);

	dt_free(dtp, pcb->pcb_asxrefs);
	dt_difo_free(dtp, pcb->pcb_difo);

	free(pcb->pcb_filetag);
	free(pcb->pcb_sflagv);

	dtp->dt_pcb = pcb->pcb_prev;
	bzero(pcb, sizeof (dt_pcb_t));
	yyinit(dtp->dt_pcb);
}
Beispiel #21
0
static void
dt_proc_destroy(dtrace_hdl_t *dtp, struct ps_prochandle *P)
{
	dt_proc_t *dpr = dt_proc_lookup(dtp, P, B_FALSE);
	dt_proc_hash_t *dph = dtp->dt_procs;
	dt_proc_notify_t *npr, **npp;
	int rflag;

	assert(dpr != NULL);

	/*
	 * If neither PR_KLC nor PR_RLC is set, then the process is stopped by
	 * an external debugger and we were waiting in dt_proc_waitrun().
	 * Leave the process in this condition using PRELEASE_HANG.
	 */
printf("dt_proc_destroy flags=%d\n", Pstatus(dpr->dpr_proc)->pr_flags);
	if (!(Pstatus(dpr->dpr_proc)->pr_flags & (PR_KLC | PR_RLC))) {
		dt_dprintf("abandoning pid %d\n", (int)dpr->dpr_pid);
		rflag = PRELEASE_HANG;
	} else {
		dt_dprintf("releasing pid %d\n", (int)dpr->dpr_pid);
		rflag = 0; /* apply kill or run-on-last-close */
	}

	if (dpr->dpr_tid) {
		/*
		 * Set the dpr_quit flag to tell the daemon thread to exit.  We
		 * send it a SIGCANCEL to poke it out of PCWSTOP or any other
		 * long-term /proc system call.  Our daemon threads have POSIX
		 * cancellation disabled, so EINTR will be the only effect.  We
		 * then wait for dpr_done to indicate the thread has exited.
		 *
		 * We can't use pthread_kill() to send SIGCANCEL because the
		 * interface forbids it and we can't use pthread_cancel()
		 * because with cancellation disabled it won't actually
		 * send SIGCANCEL to the target thread, so we use _lwp_kill()
		 * to do the job.  This is all built on evil knowledge of
		 * the details of the cancellation mechanism in libc.
		 */
		(void) pthread_mutex_lock(&dpr->dpr_lock);
		dpr->dpr_quit = B_TRUE;
#if defined(sun)
		(void) _lwp_kill(dpr->dpr_tid, SIGCANCEL);
#else
		(void) pthread_kill(dpr->dpr_tid, SIGUSR1);
#endif

		/*
		 * If the process is currently idling in dt_proc_stop(), re-
		 * enable breakpoints and poke it into running again.
		 */
		if (dpr->dpr_stop & DT_PROC_STOP_IDLE) {
			dt_proc_bpenable(dpr);
			dpr->dpr_stop &= ~DT_PROC_STOP_IDLE;
			(void) pthread_cond_broadcast(&dpr->dpr_cv);
		}

		while (!dpr->dpr_done)
			(void) pthread_cond_wait(&dpr->dpr_cv, &dpr->dpr_lock);

		(void) pthread_mutex_unlock(&dpr->dpr_lock);
	}

	/*
	 * Before we free the process structure, remove this dt_proc_t from the
	 * lookup hash, and then walk the dt_proc_hash_t's notification list
	 * and remove this dt_proc_t if it is enqueued.
	 */
	(void) pthread_mutex_lock(&dph->dph_lock);
	(void) dt_proc_lookup(dtp, P, B_TRUE);
	npp = &dph->dph_notify;

	while ((npr = *npp) != NULL) {
		if (npr->dprn_dpr == dpr) {
			*npp = npr->dprn_next;
			dt_free(dtp, npr);
		} else {
			npp = &npr->dprn_next;
		}
	}

	(void) pthread_mutex_unlock(&dph->dph_lock);

	/*
	 * Remove the dt_proc_list from the LRU list, release the underlying
	 * libproc handle, and free our dt_proc_t data structure.
	 */
	if (dpr->dpr_cacheable) {
		assert(dph->dph_lrucnt != 0);
		dph->dph_lrucnt--;
	}

	dt_list_delete(&dph->dph_lrulist, dpr);
	Prelease(dpr->dpr_proc, rflag);
	dt_free(dtp, dpr);
}
Beispiel #22
0
static int
dt_strdata_add(dtrace_hdl_t *dtp, dtrace_recdesc_t *rec, void ***data, int *max)
{
	int maxformat;
	dtrace_fmtdesc_t fmt;
	void *result;

	if (rec->dtrd_format == 0)
		return (0);

	if (rec->dtrd_format <= *max &&
	    (*data)[rec->dtrd_format - 1] != NULL) {
		return (0);
	}

	bzero(&fmt, sizeof (fmt));
	fmt.dtfd_format = rec->dtrd_format;
	fmt.dtfd_string = NULL;
	fmt.dtfd_length = 0;

	if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1)
		return (dt_set_errno(dtp, errno));

	if ((fmt.dtfd_string = dt_alloc(dtp, fmt.dtfd_length)) == NULL)
		return (dt_set_errno(dtp, EDT_NOMEM));

	if (dt_ioctl(dtp, DTRACEIOC_FORMAT, &fmt) == -1) {
		free(fmt.dtfd_string);
		return (dt_set_errno(dtp, errno));
	}

	while (rec->dtrd_format > (maxformat = *max)) {
		int new_max = maxformat ? (maxformat << 1) : 1;
		size_t nsize = new_max * sizeof (void *);
		size_t osize = maxformat * sizeof (void *);
		void **new_data = dt_zalloc(dtp, nsize);

		if (new_data == NULL) {
			dt_free(dtp, fmt.dtfd_string);
			return (dt_set_errno(dtp, EDT_NOMEM));
		}

		bcopy(*data, new_data, osize);
		free(*data);

		*data = new_data;
		*max = new_max;
	}

	switch (rec->dtrd_action) {
	case DTRACEACT_DIFEXPR:
		result = fmt.dtfd_string;
		break;
	case DTRACEACT_PRINTA:
		result = dtrace_printa_create(dtp, fmt.dtfd_string);
		dt_free(dtp, fmt.dtfd_string);
		break;
	default:
		result = dtrace_printf_create(dtp, fmt.dtfd_string);
		dt_free(dtp, fmt.dtfd_string);
		break;
	}

	if (result == NULL)
		return (-1);

	(*data)[rec->dtrd_format - 1] = result;

	return (0);
}
/*
 * dt_free_w_debug
 *
 * Wrapper for the dt_free function used in debug mode to print out info on
 * what memory has been freed and from where.
 *
 * DT_FREE resolves to this when DEBUG is defined.
 *
 * Parameters: object - The object to be freed.
 *             file - The value of __FILE__ in the calling function.
 *             line - The line number of the calling function.
 */
void dt_free_w_debug(void *object, char *file, int line)
{
    dt_free(object);

    DT_MEM_LOG("Freed object: %s(%i)\n", file, line);
}
Beispiel #24
0
int main(void)
{
	struct dt_node *root, *c1, *c2, *gc1, *gc2, *gc3, *ggc1, *i;
	const struct dt_property *p;
	struct dt_property *p2;
	unsigned int n;

	root = dt_new_root("root");
	assert(!list_top(&root->properties, struct dt_property, list));
	c1 = dt_new(root, "c1");
	assert(!list_top(&c1->properties, struct dt_property, list));
	c2 = dt_new(root, "c2");
	assert(!list_top(&c2->properties, struct dt_property, list));
	gc1 = dt_new(c1, "gc1");
	assert(!list_top(&gc1->properties, struct dt_property, list));
	gc2 = dt_new(c1, "gc2");
	assert(!list_top(&gc2->properties, struct dt_property, list));
	gc3 = dt_new(c1, "gc3");
	assert(!list_top(&gc3->properties, struct dt_property, list));
	ggc1 = dt_new(gc1, "ggc1");
	assert(!list_top(&ggc1->properties, struct dt_property, list));

	for (n = 0, i = dt_first(root); i; i = dt_next(root, i), n++) {
		assert(!list_top(&i->properties, struct dt_property, list));
		dt_add_property_cells(i, "visited", 1);
	}
	assert(n == 6);

	for (n = 0, i = dt_first(root); i; i = dt_next(root, i), n++) {
		p = list_top(&i->properties, struct dt_property, list);
		assert(strcmp(p->name, "visited") == 0);
		assert(p->len == sizeof(u32));
		assert(fdt32_to_cpu(*(u32 *)p->prop) == 1);
	}
	assert(n == 6);

	dt_add_property_cells(c1, "some-property", 1, 2, 3);
	p = dt_find_property(c1, "some-property");
	assert(p);
	assert(strcmp(p->name, "some-property") == 0);
	assert(p->len == sizeof(u32) * 3);
	assert(fdt32_to_cpu(*(u32 *)p->prop) == 1);
	assert(fdt32_to_cpu(*((u32 *)p->prop + 1)) == 2);
	assert(fdt32_to_cpu(*((u32 *)p->prop + 2)) == 3);

	/* Test freeing a single node */
	assert(!list_empty(&gc1->children));
	dt_free(ggc1);
	assert(list_empty(&gc1->children));

	/* Test rodata logic. */
	assert(!is_rodata("hello"));
	assert(is_rodata(__rodata_start));
	strcpy(__rodata_start, "name");
	ggc1 = dt_new(root, __rodata_start);
	assert(ggc1->name == __rodata_start);

	/* Test string node. */
	dt_add_property_string(ggc1, "somestring", "someval");
	assert(dt_has_node_property(ggc1, "somestring", "someval"));
	assert(!dt_has_node_property(ggc1, "somestrin", "someval"));
	assert(!dt_has_node_property(ggc1, "somestring", "someva"));
	assert(!dt_has_node_property(ggc1, "somestring", "somevale"));

	/* Test resizing property. */
	p = p2 = __dt_find_property(c1, "some-property");
	assert(p);
	n = p2->len;
	while (p2 == p) {
		n *= 2;
		dt_resize_property(&p2, n);
	}

	assert(dt_find_property(c1, "some-property") == p2);
	list_check(&c1->properties, "properties after resizing");

	dt_del_property(c1, p2);
	list_check(&c1->properties, "properties after delete");

	/* No leaks for valgrind! */
	dt_free(root);
	return 0;
}
Beispiel #25
0
void
dtrace_dof_destroy(dtrace_hdl_t *dtp, void *dof)
{
	dt_free(dtp, dof);
}
Beispiel #26
0
int main(int argc, char **argv)
{
    struct dt_dentry *probe;
    struct cfwk_dir curdir;
    int full = 0;
    int lookup = 0;
    char *host;
    int i;
    char *oldtree = NULL;
    FILE *oldfile;
    char *port = NULL;
    char *server_cp = NULL;
    CURLcode rcode;

    for (i = 1; i < argc; i++) {
        if (argv[i][0] != '-')
            break;
        if (argv[i][1] == '-' && argv[i][2] == 0) {
            i++;
            break;
        }
        switch (argv[i][1]) {
            case 'f':
                full = 1;
                break;
            case 'p':
                port = &argv[i][2];
                break;
            case 'l':
                lookup = 1;
                break;
            case 'C':
                i++;
                if (i >= argc)
                    usage(argv[0], ESTAT_FAILURE);
                server_cp = argv[i];
                break;
            case 'u':
                i++;
                if (i >= argc)
                    usage(argv[0], ESTAT_FAILURE);
                oldtree = argv[i];
                break;
            case 'h':
                usage(argv[0], ESTAT_SUCCESS);
            default:
                usage(argv[0], ESTAT_FAILURE);
        }
    }
    
    if (i + 1 != argc)
        usage(argv[0], ESTAT_FAILURE);

    if ((rcode = curl_global_init(CURL_GLOBAL_NOTHING)) != CURLE_OK) {
        LOG_ERR("curl_global_init() returned non-zero: %s\n",
                curl_easy_strerror(rcode));
        exit(ESTAT_FAILURE);
    }

    host = argv[i];

    if (cfwk_open(&curdir, host, port, server_cp) < 0)
        exit(ESTAT_NOCONNECT);

    if (lookup) {
        probe = cfwk_walker.readdir(&curdir);
        cfwk_close(&curdir);
        if (probe != NULL) {
            dt_free(probe);
            exit(ESTAT_SUCCESS);
        }
        else
            exit(ESTAT_FAILURE);
    }

    if (full)
        dt_full(&cfwk_walker, &curdir);
    else if (oldtree) {
        if ((oldfile = fopen(oldtree, "r")) == NULL) {
            LOG_ERRNO("Can't open file %s\n", oldtree);
            exit(ESTAT_FAILURE);
        }
        dt_diff(oldfile, &cfwk_walker, &curdir);
        fclose(oldfile);
    } else
        dt_reverse(&cfwk_walker, &curdir);

    cfwk_close(&curdir);
    curl_global_cleanup();

    return ESTAT_SUCCESS;
}
int main(void)
{
	const struct dt_property *names, *ranges;
	struct mem_region *r;
	unsigned int i, l, c;
	uint64_t *rangep;
	const char *name;
	void *buf;

	/* Use malloc for the heap, so valgrind can find issues. */
	skiboot_heap.start = (long)real_malloc(TEST_HEAP_SIZE);
	skiboot_heap.len = TEST_HEAP_SIZE;
	skiboot_os_reserve.len = skiboot_heap.start;

	dt_root = dt_new_root("");
	dt_add_property_cells(dt_root, "#address-cells", 2);
	dt_add_property_cells(dt_root, "#size-cells", 2);

	buf = real_malloc(1024*1024);
	add_mem_node((unsigned long)buf, 1024*1024);

	/* Now convert. */
	mem_region_init();

	/* create our reservations */
	for (i = 0; i < ARRAY_SIZE(test_regions); i++)
		mem_reserve(test_regions[i].name, test_regions[i].addr, 0x1000);

	/* release unused */
	mem_region_release_unused();

	/* and create reservations */
	mem_region_add_dt_reserved();

	/* ensure we can't create further reservations */
	r = new_region("test.4", 0x5000, 0x1000, NULL, REGION_RESERVED);
	assert(!add_region(r));

	/* check dt properties */
	names = dt_find_property(dt_root, "reserved-names");
	ranges = dt_find_property(dt_root, "reserved-ranges");

	assert(names && ranges);

	/* walk through names & ranges properies, ensuring that the test
	 * regions are all present */
	for (name = names->prop, rangep = (uint64_t *)ranges->prop, c = 0;
			name < names->prop + names->len;
			name += l, rangep += 2) {
		uint64_t addr;

		addr = dt_get_number(rangep, 2);
		l = strlen(name) + 1;

		for (i = 0; i < ARRAY_SIZE(test_regions); i++) {
			if (strcmp(test_regions[i].name, name))
				continue;
			assert(test_regions[i].addr == addr);
			assert(!test_regions[i].found);
			test_regions[i].found = true;
			c++;
		}
	}

	assert(c == ARRAY_SIZE(test_regions));

	dt_free(dt_root);
	real_free(buf);
	real_free((void *)(long)skiboot_heap.start);
	return 0;
}
Beispiel #28
0
dt_xlator_t *
dt_xlator_create(dtrace_hdl_t *dtp,
    const dtrace_typeinfo_t *src, const dtrace_typeinfo_t *dst,
    const char *name, dt_node_t *members, dt_node_t *nodes)
{
	dt_xlator_t *dxp = dt_zalloc(dtp, sizeof (dt_xlator_t));
	dtrace_typeinfo_t ptr = *dst;
	dt_xlator_t **map;
	dt_node_t *dnp;
	uint_t kind;

	if (dxp == NULL)
		return (NULL);

	dxp->dx_hdl = dtp;
	dxp->dx_id = dtp->dt_xlatorid++;
	dxp->dx_gen = dtp->dt_gen;
	dxp->dx_arg = -1;

	if ((map = dt_alloc(dtp, sizeof (void *) * (dxp->dx_id + 1))) == NULL) {
		dt_free(dtp, dxp);
		return (NULL);
	}

	dt_list_append(&dtp->dt_xlators, dxp);
	bcopy(dtp->dt_xlatormap, map, sizeof (void *) * dxp->dx_id);
	dt_free(dtp, dtp->dt_xlatormap);
	dtp->dt_xlatormap = map;
	dtp->dt_xlatormap[dxp->dx_id] = dxp;

	if (dt_type_pointer(&ptr) == -1) {
		ptr.dtt_ctfp = NULL;
		ptr.dtt_type = CTF_ERR;
	}

	dxp->dx_ident = dt_ident_create(name ? name : "T",
	    DT_IDENT_SCALAR, DT_IDFLG_REF | DT_IDFLG_ORPHAN, 0,
	    _dtrace_defattr, 0, &dt_idops_thaw, NULL, dtp->dt_gen);

	if (dxp->dx_ident == NULL)
		goto err; /* no memory for identifier */

	dxp->dx_ident->di_ctfp = src->dtt_ctfp;
	dxp->dx_ident->di_type = src->dtt_type;

	/*
	 * If an input parameter name is given, this is a static translator
	 * definition: create an idhash and identifier for the parameter.
	 */
	if (name != NULL) {
		dxp->dx_locals = dt_idhash_create("xlparams", NULL, 0, 0);

		if (dxp->dx_locals == NULL)
			goto err; /* no memory for identifier hash */

		dt_idhash_xinsert(dxp->dx_locals, dxp->dx_ident);
	}

	dxp->dx_souid.di_name = "translator";
	dxp->dx_souid.di_kind = DT_IDENT_XLSOU;
	dxp->dx_souid.di_flags = DT_IDFLG_REF;
	dxp->dx_souid.di_id = dxp->dx_id;
	dxp->dx_souid.di_attr = _dtrace_defattr;
	dxp->dx_souid.di_ops = &dt_idops_thaw;
	dxp->dx_souid.di_data = dxp;
	dxp->dx_souid.di_ctfp = dst->dtt_ctfp;
	dxp->dx_souid.di_type = dst->dtt_type;
	dxp->dx_souid.di_gen = dtp->dt_gen;

	dxp->dx_ptrid.di_name = "translator";
	dxp->dx_ptrid.di_kind = DT_IDENT_XLPTR;
	dxp->dx_ptrid.di_flags = DT_IDFLG_REF;
	dxp->dx_ptrid.di_id = dxp->dx_id;
	dxp->dx_ptrid.di_attr = _dtrace_defattr;
	dxp->dx_ptrid.di_ops = &dt_idops_thaw;
	dxp->dx_ptrid.di_data = dxp;
	dxp->dx_ptrid.di_ctfp = ptr.dtt_ctfp;
	dxp->dx_ptrid.di_type = ptr.dtt_type;
	dxp->dx_ptrid.di_gen = dtp->dt_gen;

	/*
	 * If a deferred pragma is pending on the keyword "translator", run all
	 * the deferred pragmas on dx_souid and then copy results to dx_ptrid.
	 * See the code in dt_pragma.c for details on deferred ident pragmas.
	 */
	if (dtp->dt_globals->dh_defer != NULL && yypcb->pcb_pragmas != NULL &&
	    dt_idhash_lookup(yypcb->pcb_pragmas, "translator") != NULL) {
		dtp->dt_globals->dh_defer(dtp->dt_globals, &dxp->dx_souid);
		dxp->dx_ptrid.di_attr = dxp->dx_souid.di_attr;
		dxp->dx_ptrid.di_vers = dxp->dx_souid.di_vers;
	}

	dxp->dx_src_ctfp = src->dtt_ctfp;
	dxp->dx_src_type = src->dtt_type;
	dxp->dx_src_base = ctf_type_resolve(src->dtt_ctfp, src->dtt_type);

	dxp->dx_dst_ctfp = dst->dtt_ctfp;
	dxp->dx_dst_type = dst->dtt_type;
	dxp->dx_dst_base = ctf_type_resolve(dst->dtt_ctfp, dst->dtt_type);

	kind = ctf_type_kind(dst->dtt_ctfp, dxp->dx_dst_base);
	assert(kind == CTF_K_STRUCT || kind == CTF_K_UNION);

	/*
	 * If no input parameter is given, we're making a dynamic translator:
	 * create member nodes for every member of the output type.  Otherwise
	 * retain the member and allocation node lists presented by the parser.
	 */
	if (name == NULL) {
		if (ctf_member_iter(dxp->dx_dst_ctfp, dxp->dx_dst_base,
		    dt_xlator_create_member, dxp) != 0)
			goto err;
	} else {
		dxp->dx_members = members;
		dxp->dx_nodes = nodes;
	}

	/*
	 * Assign member IDs to each member and allocate space for DIFOs
	 * if and when this translator is eventually compiled.
	 */
	for (dnp = dxp->dx_members; dnp != NULL; dnp = dnp->dn_list) {
		dnp->dn_membxlator = dxp;
		dnp->dn_membid = dxp->dx_nmembers++;
	}

	dxp->dx_membdif = dt_zalloc(dtp,
	    sizeof (dtrace_difo_t *) * dxp->dx_nmembers);

	if (dxp->dx_membdif == NULL) {
		dxp->dx_nmembers = 0;
		goto err;
	}

	return (dxp);

err:
	dt_xlator_destroy(dtp, dxp);
	return (NULL);
}
Beispiel #29
0
int
dt_probe_define(dt_provider_t *pvp, dt_probe_t *prp,
    const char *fname, const char *rname, uint32_t offset, int isenabled)
{
	dtrace_hdl_t *dtp = pvp->pv_hdl;
	dt_probe_instance_t *pip;
	uint32_t **offs;
	uint_t *noffs, *maxoffs;

	assert(fname != NULL);

	for (pip = prp->pr_inst; pip != NULL; pip = pip->pi_next) {
		if (strcmp(pip->pi_fname, fname) == 0 &&
		    ((rname == NULL && pip->pi_rname == NULL) ||
		    (rname != NULL && pip->pi_rname != NULL &&
		    strcmp(pip->pi_rname, rname) == 0)))
			break;
	}

	if (pip == NULL) {
		if ((pip = dt_zalloc(dtp, sizeof (*pip))) == NULL)
			return (-1);

		if ((pip->pi_offs = dt_zalloc(dtp, sizeof (uint32_t))) == NULL)
			goto nomem;

		if ((pip->pi_enoffs = dt_zalloc(dtp,
		    sizeof (uint32_t))) == NULL)
			goto nomem;

		if ((pip->pi_fname = strdup(fname)) == NULL)
			goto nomem;

		if (rname != NULL && (pip->pi_rname = strdup(rname)) == NULL)
			goto nomem;

		pip->pi_noffs = 0;
		pip->pi_maxoffs = 1;
		pip->pi_nenoffs = 0;
		pip->pi_maxenoffs = 1;

		pip->pi_next = prp->pr_inst;

		prp->pr_inst = pip;
	}

	if (isenabled) {
		offs = &pip->pi_enoffs;
		noffs = &pip->pi_nenoffs;
		maxoffs = &pip->pi_maxenoffs;
	} else {
		offs = &pip->pi_offs;
		noffs = &pip->pi_noffs;
		maxoffs = &pip->pi_maxoffs;
	}

	if (*noffs == *maxoffs) {
		uint_t new_max = *maxoffs * 2;
		uint32_t *new_offs = dt_alloc(dtp, sizeof (uint32_t) * new_max);

		if (new_offs == NULL)
			return (-1);

		bcopy(*offs, new_offs, sizeof (uint32_t) * *maxoffs);

		dt_free(dtp, *offs);
		*maxoffs = new_max;
		*offs = new_offs;
	}

	dt_dprintf("defined probe %s %s:%s %s() +0x%x (%s)\n",
	    isenabled ? "(is-enabled)" : "",
	    pvp->pv_desc.dtvd_name, prp->pr_ident->di_name, fname, offset,
	    rname != NULL ? rname : fname);

	assert(*noffs < *maxoffs);
	(*offs)[(*noffs)++] = offset;

	return (0);

nomem:
	dt_free(dtp, pip->pi_fname);
	dt_free(dtp, pip->pi_enoffs);
	dt_free(dtp, pip->pi_offs);
	dt_free(dtp, pip);
	return (dt_set_errno(dtp, EDT_NOMEM));
}
Beispiel #30
0
/*
 * The #pragma depends_on directive can be used to express a dependency on a
 * module, provider or library which if not present will cause processing to
 * abort.
 */
static void
dt_pragma_depends(const char *prname, dt_node_t *cnp)
{
	dtrace_hdl_t *dtp = yypcb->pcb_hdl;
	dt_node_t *nnp = cnp ? cnp->dn_list : NULL;
	int found;
	dt_lib_depend_t *dld;
	char lib[MAXPATHLEN];
	size_t plen;
	char *provs, *cpy, *tok;

	if (cnp == NULL || nnp == NULL ||
	    cnp->dn_kind != DT_NODE_IDENT || nnp->dn_kind != DT_NODE_IDENT) {
		xyerror(D_PRAGMA_MALFORM, "malformed #pragma %s "
		    "<class> <name>\n", prname);
	}

	if (strcmp(cnp->dn_string, "provider") == 0) {
		/*
		 * First try to get the provider list using the
		 * debug.dtrace.providers sysctl, since that'll work even if
		 * we're not running as root.
		 */
		provs = NULL;
		if (sysctlbyname("debug.dtrace.providers", NULL, &plen, NULL, 0) ||
		    ((provs = dt_alloc(dtp, plen)) == NULL) ||
		    sysctlbyname("debug.dtrace.providers", provs, &plen, NULL, 0))
			found = dt_provider_lookup(dtp, nnp->dn_string) != NULL;
		else {
			found = B_FALSE;
			for (cpy = provs; (tok = strsep(&cpy, " ")) != NULL; )
				if (strcmp(tok, nnp->dn_string) == 0) {
					found = B_TRUE;
					break;
				}
			if (found == B_FALSE)
				found = dt_provider_lookup(dtp,
				    nnp->dn_string) != NULL;
		}
		if (provs != NULL)
			dt_free(dtp, provs);
	} else if (strcmp(cnp->dn_string, "module") == 0) {
		dt_module_t *mp = dt_module_lookup_by_name(dtp, nnp->dn_string);
		found = mp != NULL && dt_module_getctf(dtp, mp) != NULL;
	} else if (strcmp(cnp->dn_string, "library") == 0) {
		if (yypcb->pcb_cflags & DTRACE_C_CTL) {
			assert(dtp->dt_filetag != NULL);

			dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
			    sizeof (lib));

			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
			    dtp->dt_filetag);
			assert(dld != NULL);

			if ((dt_lib_depend_add(dtp, &dld->dtld_dependencies,
			    lib)) != 0) {
				xyerror(D_PRAGMA_DEPEND,
				    "failed to add dependency %s:%s\n", lib,
				    dtrace_errmsg(dtp, dtrace_errno(dtp)));
			}
		} else {
			/*
			 * By this point we have already performed a topological
			 * sort of the dependencies; we process this directive
			 * as satisfied as long as the dependency was properly
			 * loaded.
			 */
			if (dtp->dt_filetag == NULL)
				xyerror(D_PRAGMA_DEPEND, "main program may "
				    "not explicitly depend on a library");

			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep,
			    dtp->dt_filetag);
			assert(dld != NULL);

			dt_pragma_depends_finddep(dtp, nnp->dn_string, lib,
			    sizeof (lib));
			dld = dt_lib_depend_lookup(&dtp->dt_lib_dep_sorted,
			    lib);
			assert(dld != NULL);

			if (!dld->dtld_loaded)
				xyerror(D_PRAGMA_DEPEND, "program requires "
				    "library \"%s\" which failed to load",
				    lib);
		}

		found = B_TRUE;
	} else {
		xyerror(D_PRAGMA_INVAL, "invalid class %s "
		    "specified by #pragma %s\n", cnp->dn_string, prname);
	}

	if (!found) {
		xyerror(D_PRAGMA_DEPEND, "program requires %s %s\n",
		    cnp->dn_string, nnp->dn_string);
	}
}