Beispiel #1
0
static PyObject *
attr_dir_get(PyObject *_self, PyObject *args)
{
	attr_dir_object *self = (attr_dir_object*)_self;
	PyObject *key, *failobj;
	kdump_ctx *ctx;
	kdump_attr_ref_t ref;
	kdump_attr_t attr;
	kdump_status status;
	int res;

	failobj = Py_None;
	if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj))
		return NULL;

	res = lookup_attribute(self, key, &ref);
	if (res < 0)
		return NULL;
	else if (res == 0)
		goto notfound;

	ctx = self->kdumpfile->ctx;
	status = kdump_attr_ref_get(ctx, &ref, &attr);
	if (status == kdump_ok)
		return attr_new(self->kdumpfile, &ref, &attr);

	if (status != kdump_nodata) {
		PyErr_SetString(exception_map(status), kdump_err_str(ctx));
		return NULL;
	}

 notfound:
	Py_INCREF(failobj);
	return failobj;
}
Beispiel #2
0
/*
 * The "initial exec" tls model.
 */
static NODE *
tlsinitialexec(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * movq %fs:0,%rax
	 * addq x@GOTTPOFF(%rip),%rax
	 */

	q = bcon(0);
	q->n_type = STRTY;

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=r", r);
	r = block(XASM, r, q, INT, 0, 0);

	s1 = "movq %%fs:0,%0\n\taddq ";
	s2 = "@GOTTPOFF(%%rip),%0";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2);

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
Beispiel #3
0
static PyObject *
dict_setdefault(PyObject *_self, PyObject *args)
{
	attr_dir_object *self = (attr_dir_object*)_self;
	PyObject *key, *failobj;
	PyObject *val = NULL;
	kdump_ctx *ctx;
	kdump_attr_ref_t ref;
	kdump_attr_t attr;
	kdump_status status;

	failobj = Py_None;
	if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &key, &failobj))
		return NULL;

	if (get_attribute(self, key, &ref) <= 0)
		return NULL;

	ctx = self->kdumpfile->ctx;
	status = kdump_attr_ref_get(ctx, &ref, &attr);
	if (status == kdump_ok)
		val = attr_new(self->kdumpfile, &ref, &attr);
	else if (status == kdump_nodata)
		val = (set_attribute(self, &ref, failobj) == 0)
			? failobj
			: NULL;
	else {
		PyErr_SetString(exception_map(status), kdump_err_str(ctx));
		val = NULL;
	}
	kdump_attr_unref(ctx, &ref);

	Py_XINCREF(val);
	return val;
}
Beispiel #4
0
static struct symtab *
addstr(char *n)
{
	NODE *p = block(NAME, NIL, NIL, FLOAT, 0, 0);
	struct symtab *sp;
	NODE *q;
	struct attr *ap;
	struct rstack *rp;
	extern struct rstack *rpole;

	p->n_type = ctype(ULONGLONG);
	rpole = rp = bstruct(NULL, STNAME, NULL);
	soumemb(p, loti, 0);
	soumemb(p, hiti, 0);
	q = dclstruct(rp);
	sp = q->n_sp = lookup(addname(n), 0);
	defid(q, TYPEDEF);
	ap = attr_new(GCC_ATYP_MODE, 3);
	ap->sarg(0) = addname("TI");
	ap->iarg(1) = 0;
	sp->sap = attr_add(sp->sap, ap);
	nfree(q);
	nfree(p);

	return sp;
}
Beispiel #5
0
static PyObject *
attr_dir_subscript(PyObject *_self, PyObject *key)
{
	attr_dir_object *self = (attr_dir_object*)_self;
	kdump_ctx *ctx;
	kdump_attr_t attr;
	kdump_attr_ref_t ref;
	kdump_status status;

	if (get_attribute(self, key, &ref) <= 0)
		return NULL;

	ctx = self->kdumpfile->ctx;
	status = kdump_attr_ref_get(ctx, &ref, &attr);
	if (status == kdump_ok)
		return attr_new(self->kdumpfile, &ref, &attr);

	if (status == kdump_nodata)
		PyErr_SetObject(PyExc_KeyError, key);
	else
		PyErr_SetString(exception_map(status), kdump_err_str(ctx));

	kdump_attr_unref(ctx, &ref);
	return NULL;
}
Beispiel #6
0
void
myp2tree(NODE *p)
{
	struct attr *ap;
	struct symtab *sp, sps;
	static int dblxor, fltxor;
	int codeatyp(NODE *);

	if (p->n_op == STCALL || p->n_op == USTCALL) {
		/* save struct encoding */
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_CMPLRET, 1));
		ap->iarg(0) = codeatyp(p);
	}

	if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
		/* Store xor code for sign change */
		if (dblxor == 0) {
			dblxor = getlab();
			fltxor = getlab();
			sps.stype = LDOUBLE;
			sps.squal = CON >> TSHIFT;
			sps.sflags = sps.sclass = 0;
			sps.sname = "";
			sps.slevel = 1;
			sps.sap = NULL;
			sps.soffset = dblxor;
			locctr(DATA, &sps);
			defloc(&sps);
			printf("\t.long 0,0x80000000,0,0\n");
			printf(LABFMT ":\n", fltxor);
			printf("\t.long 0x80000000,0,0,0\n");
		}
		p->n_ap = attr_add(p->n_ap,
		    ap = attr_new(ATTR_AMD64_XORLBL, 1));
		ap->iarg(0) = p->n_type == FLOAT ? fltxor : dblxor;
		return;
	}
Beispiel #7
0
/*
 * Check if we may have to do a cast to/from TI.
 */
NODE *
gcc_eval_ticast(int op, NODE *p1, NODE *p2)
{
	struct attr *a1, *a2;
	int t;

	a2 = NULL; /* XXX flow analysis */
	if ((a1 = isti(p1)) == NULL && (a2 = isti(p2)) == NULL)
		return NIL;

	if (op == RETURN)
		p1 = p1tcopy(p1);
	if (a1 == NULL) {
		if (a2 == NULL)
			cerror("gcc_eval_ticast error");
		switch (p1->n_type) {
		case LDOUBLE:
			p2 = doacall(floatuntixfsp,
			    nametree(floatuntixfsp), p2);
			tfree(p1);
			break;
		case ULONG:
		case LONG:
			p2 = cast(structref(p2, DOT, loti), p1->n_type, 0);
			tfree(p1);
			break;
		case VOID:
			return NIL;
		default:
			uerror("gcc_eval_ticast: %d", p1->n_type);
		}
		return p2;
	}
	/* p2 can be anything, but we must cast it to p1 */
	t = a1->iarg(1);

	if (p2->n_type == STRTY &&
	    (a2 = attr_find(p2->n_ap, GCC_ATYP_MODE)) &&
	    strcmp(a2->sarg(0), TISTR) == 0) {
		/* Already TI, just add extra mode bits */
		a2 = attr_new(GCC_ATYP_MODE, 3);
		a2->sarg(0) = TISTR;
		a2->iarg(1) = t;
		p2->n_ap = attr_add(p2->n_ap, a2);
	} else  {
		p2 = ticast(p2, t);
	}
	tfree(p1);
	return p2;
}
Beispiel #8
0
/*
 * Make a symtab entry for PIC use.
 */
static struct symtab *
picsymtab(char *p, char *s, char *s2)
{
	struct symtab *sp = IALLOC(sizeof(struct symtab));
	size_t len = strlen(p) + strlen(s) + strlen(s2) + 1;

	sp->sname = IALLOC(len);
	strlcpy(sp->sname, p, len);
	strlcat(sp->sname, s, len);
	strlcat(sp->sname, s2, len);
	sp->sap = attr_new(ATTR_SONAME, 1);
	sp->sap->sarg(0) = sp->sname;
	sp->sclass = EXTERN;
	sp->sflags = sp->slevel = 0;
	return sp;
}
Beispiel #9
0
/*
 * Create a reference for a TLS variable.
 * This is the "General dynamic" version.
 */
static NODE *
tlspic(NODE *p)
{
	NODE *q, *r, *s;
	char *s1, *s2;

	/*
	 * .byte   0x66
	 * leaq x@TLSGD(%rip),%rdi
	 * .word   0x6666
	 * rex64
	 * call __tls_get_addr@PLT
	 */

	/* Need the .byte stuff around.  Why? */
	/* Use inline assembler */
	q = mkx("%rdx", bcon(0));
	q = cmop(q, mkx("%rcx", bcon(0)));
	q = cmop(q, mkx("%rsi", bcon(0)));
	q = cmop(q, mkx("%rdi", bcon(0)));
	q = cmop(q, mkx("%r8", bcon(0)));
	q = cmop(q, mkx("%r9", bcon(0)));
	q = cmop(q, mkx("%r10", bcon(0)));
	q = cmop(q, mkx("%r11", bcon(0)));

	s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
	r = mkx("=a", r);
	r = block(XASM, r, q, INT, 0, 0);

	/* Create the magic string */
	s1 = ".byte 0x66\n\tleaq ";
	s2 = "@TLSGD(%%rip),%%rdi\n"
	    "\t.word 0x6666\n\trex64\n\tcall __tls_get_addr@PLT";
	if (attr_find(p->n_sp->sap, ATTR_SONAME) == NULL) {
		p->n_sp->sap = attr_add(p->n_sp->sap, attr_new(ATTR_SONAME, 1));
		p->n_sp->sap->sarg(0) = p->n_sp->sname;
	}
	r->n_name = addstring(mk3str(s1,
	    attr_find(p->n_sp->sap, ATTR_SONAME)->sarg(0), s2));

	r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
	r = buildtree(UMUL, r, NIL);
	tfree(p);
	return r;
}
Beispiel #10
0
static PyObject *
attr_iteritem_next(PyObject *_self)
{
	attr_iter_object *self = (attr_iter_object*)_self;
	kdump_ctx *ctx;
	kdump_attr_t attr;
	kdump_status status;
	PyObject *key, *value, *result;

	if (!self->iter.key)
		return NULL;

	ctx = self->kdumpfile->ctx;
	status = kdump_attr_ref_get(ctx, &self->iter.pos, &attr);
	if (status != kdump_ok) {
		PyErr_SetString(exception_map(status), kdump_err_str(ctx));
		return NULL;
	}

	result = PyTuple_New(2);
	if (result == NULL)
		return NULL;
	key = PyString_FromString(self->iter.key);
	if (!key)
		goto err_result;
	value = attr_new(self->kdumpfile, &self->iter.pos, &attr);
	if (!value)
		goto err_key;

	PyTuple_SET_ITEM(result, 0, key);
	PyTuple_SET_ITEM(result, 1, value);
	return attr_iter_advance(self, result);

 err_key:
	Py_DECREF(key);
 err_result:
	Py_DECREF(result);
	return NULL;
}
Beispiel #11
0
static PyObject *
attr_itervalue_next(PyObject *_self)
{
	attr_iter_object *self = (attr_iter_object*)_self;
	kdump_ctx *ctx;
	kdump_attr_t attr;
	kdump_status status;
	PyObject *value;

	if (!self->iter.key)
		return NULL;

	ctx = self->kdumpfile->ctx;
	status = kdump_attr_ref_get(ctx, &self->iter.pos, &attr);
	if (status != kdump_ok) {
		PyErr_SetString(exception_map(status), kdump_err_str(ctx));
		return NULL;
	}

	value = attr_new(self->kdumpfile, &self->iter.pos, &attr);
	return attr_iter_advance(self, value);
}
Beispiel #12
0
/*
 * Parse attributes from an argument list.
 */
static struct attr *
gcc_attribs(NODE *p)
{
	NODE *q, *r;
	struct attr *ap;
	char *name = NULL, *c;
	int cw, attr, narg, i;

	if (p->n_op == NAME) {
		name = (char *)p->n_sp;
	} else if (p->n_op == CALL || p->n_op == UCALL) {
		name = (char *)p->n_left->n_sp;
	} else if (p->n_op == ICON && p->n_type == STRTY) {
		return NULL;
	} else
		cerror("bad variable attribute");

	if ((attr = amatch(name, atax, GCC_ATYP_MAX)) == 0) {
		werror("unsupported attribute '%s'", name);
		ap = NULL;
		goto out;
	}
	narg = 0;
	if (p->n_op == CALL)
		for (narg = 1, q = p->n_right; q->n_op == CM; q = q->n_left)
			narg++;

	cw = atax[attr].typ;
	if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
		uerror("wrong attribute arg count");
		return NULL;
	}
	ap = attr_new(attr, 3); /* XXX should be narg */
	q = p->n_right;

	switch (narg) {
	default:
		/* XXX */
		while (narg-- > 3) {
			r = q;
			q = q->n_left;
			tfree(r->n_right);
			nfree(r);
		}
		/* FALLTHROUGH */
	case 3:
		setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
		r = q;
		q = q->n_left;
		nfree(r);
		/* FALLTHROUGH */
	case 2:
		setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
		r = q;
		q = q->n_left;
		nfree(r);
		/* FALLTHROUGH */
	case 1:
		setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
		p->n_op = UCALL;
		/* FALLTHROUGH */
	case 0:
		break;
	}

	/* some attributes must be massaged special */
	switch (attr) {
	case GCC_ATYP_ALIGNED:
		if (narg == 0)
			ap->aa[0].iarg = ALMAX;
		else
			ap->aa[0].iarg *= SZCHAR;
		break;
	case GCC_ATYP_PACKED:
		if (narg == 0)
			ap->aa[0].iarg = 1; /* bitwise align */
		else
			ap->aa[0].iarg *= SZCHAR;
		break;

	case GCC_ATYP_MODE:
		if ((i = amatch(ap->aa[0].sarg, mods, ATSZ)) == 0)
			werror("unknown mode arg %s", ap->aa[0].sarg);
		ap->aa[0].iarg = ctype(mods[i].typ);
		break;

	case GCC_ATYP_VISIBILITY:
		c = ap->aa[0].sarg;
		if (strcmp(c, "default") && strcmp(c, "hidden") &&
		    strcmp(c, "internal") && strcmp(c, "protected"))
			werror("unknown visibility %s", c);
		break;

	case GCC_ATYP_TLSMODEL:
		c = ap->aa[0].sarg;
		if (strcmp(c, "global-dynamic") && strcmp(c, "local-dynamic") &&
		    strcmp(c, "initial-exec") && strcmp(c, "local-exec"))
			werror("unknown tls model %s", c);
		break;

	default:
		break;
	}
out:
	return ap;
}
Beispiel #13
0
/*
 * Fixup types when modes given in defid().
 */
void
gcc_modefix(NODE *p)
{
	struct attr *ap;
#ifdef TARGET_TIMODE
	struct attr *a2;
#endif
	struct symtab *sp;
	char *s;
	int i, u;

	if ((ap = attr_find(p->n_ap, GCC_ATYP_MODE)) == NULL)
		return;

	u = ISUNSIGNED(BTYPE(p->n_type));
	if ((i = amatch(ap->aa[0].sarg, mods, ATSZ)) == 0) {
		werror("unknown mode arg %s", ap->aa[0].sarg);
		return;
	}
	i = mods[i].typ;
	if (i >= 1 && i <= MAXTYPES) {
		MODTYPE(p->n_type, ctype(i));
		if (u)
			p->n_type = ENUNSIGN(p->n_type);
	} else switch (i) {
#ifdef TARGET_TIMODE
	case 800:
		if (BTYPE(p->n_type) == STRTY)
			break;
		MODTYPE(p->n_type, tisp->stype);
		p->n_df = tisp->sdf;
		p->n_ap = tisp->sap;
		if (ap->iarg(1) == u)
			break;
		/* must add a new mode struct to avoid overwriting */
		a2 = attr_new(GCC_ATYP_MODE, 3);
		a2->sarg(0) = ap->sarg(0);
		a2->iarg(1) = u;
		p->n_ap = attr_add(p->n_ap, a2);
		break;
#endif
	case FCOMPLEX:
	case COMPLEX:
	case LCOMPLEX:
		/* Destination should have been converted to a struct already */
		if (BTYPE(p->n_type) != STRTY)
			uerror("gcc_modefix: complex not STRTY");
		i -= (FCOMPLEX-FLOAT);
		ap = strattr(p->n_ap);
		sp = ap->amlist;
		if (sp->stype == (unsigned)i)
			return; /* Already correct type */
		/* we must change to another struct */
		s = i == FLOAT ? "0f" :
		    i == DOUBLE ? "0d" :
		    i == LDOUBLE ? "0l" : 0;
		sp = lookup(addname(s), 0);
		for (ap = sp->sap; ap != NULL; ap = ap->next)
			p->n_ap = attr_add(p->n_ap, attr_dup(ap));
		break;

	default:
		cerror("gcc_modefix");
	}
}
Beispiel #14
0
void
gcc_init(void)
{
	struct kw *kwp;
	NODE *p;
	TWORD t;
	int i, d_debug;

	d_debug = ddebug;
	ddebug = 0;
	for (kwp = kw; kwp->name; kwp++)
		kwp->ptr = addname(kwp->name);

	for (i = 0; i < 4; i++) {
		struct symtab *sp;
		t = ctype(g77t[i]);
		p = block(NAME, NIL, NIL, t, NULL, 0);
		sp = lookup(addname(g77n[i]), 0);
		p->n_sp = sp;
		defid(p, TYPEDEF);
		nfree(p);
	}
	ddebug = d_debug;
#ifdef TARGET_TIMODE
	{
		struct attr *ap;

		loti = addname("__loti");
		hiti = addname("__hiti");
		TISTR = addname("TI");

		tisp = addstr("0ti");

		cmpti2sp = addftn("__cmpti2", INT);
		ucmpti2sp = addftn("__ucmpti2", INT);

		addvti3sp = addftn("__addvti3", STRTY);
		addvti3sp->sap = tisp->sap;
		subvti3sp = addftn("__subvti3", STRTY);
		subvti3sp->sap = tisp->sap;
		mulvti3sp = addftn("__mulvti3", STRTY);
		mulvti3sp->sap = tisp->sap;
		divti3sp = addftn("__divti3", STRTY);
		divti3sp->sap = tisp->sap;
		modti3sp = addftn("__modti3", STRTY);
		modti3sp->sap = tisp->sap;

		ap = attr_new(GCC_ATYP_MODE, 3);
		ap->sarg(0) = TISTR;
		ap->iarg(1) = 1;
		ap = attr_add(tisp->sap, ap);
		udivti3sp = addftn("__udivti3", STRTY);
		udivti3sp->sap = ap;
		umodti3sp = addftn("__umodti3", STRTY);
		umodti3sp->sap = ap;
		ashldi3sp = addftn("__ashldi3", ctype(LONGLONG));
		ashldi3sp->sap = ap;
		ashrdi3sp = addftn("__ashrdi3", ctype(LONGLONG));
		ashrdi3sp->sap = ap;
		lshrdi3sp = addftn("__lshrdi3", ctype(LONGLONG));
		lshrdi3sp->sap = ap;

		floatuntixfsp = addftn("__floatuntixf", LDOUBLE);
	}
#endif
}