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; }
/* * 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; }
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; }
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; }
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; }
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; }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
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); }
/* * 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; }
/* * 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"); } }
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 }