/* * Create a reference for an extern variable. */ static NODE * picext(NODE *p) { NODE *q, *r; struct symtab *sp; char *name; q = tempnode(gotnr, PTR|VOID, 0, 0); name = getexname(p->n_sp); #ifdef notdef struct attr *ga; if ((ga = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) && strcmp(ga->sarg(0), "hidden") == 0) { /* For hidden vars use GOTOFF */ sp = picsymtab("", name, "@GOTOFF"); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ nfree(p); return q; } #endif sp = picsymtab("", name, "@GOT"); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, PTR|VOID, 0, 0); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ nfree(p); return q; }
/* * Create a reference for an extern variable or function. */ static NODE * picext(NODE *p) { #if defined(ELFABI) NODE *q; struct symtab *sp; char *c; if (p->n_sp->sflags & SBEENHERE) return p; #ifdef GCC_COMPAT struct attr *ga; if ((ga = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) && strcmp(ga->sarg(0), "hidden") == 0) return p; /* no GOT reference */ #endif c = getexname(p->n_sp); sp = picsymtab("", c, "@GOTPCREL"); sp->sflags |= SBEENHERE; q = block(NAME, NIL, NIL, INCREF(p->n_type), p->n_df, p->n_ap); q->n_sp = sp; q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = sp; nfree(p); return q; #elif defined(MACHOABI) return p; #endif }
/* * Called when a identifier has been declared. */ void fixdef(struct symtab *sp) { struct attr *ga; #ifdef HAVE_WEAKREF /* not many as'es have this directive */ if ((ga = attr_find(sp->sap, GCC_ATYP_WEAKREF)) != NULL) { char *wr = ga->sarg(0); char *sn = getsoname(sp); if (wr == NULL) { if ((ga = attr_find(sp->sap, GCC_ATYP_ALIAS))) { wr = ga->sarg(0); } } if (wr == NULL) printf("\t.weak %s\n", sn); else printf("\t.weakref %s,%s\n", sn, wr); } else if ((ga = attr_find(sp->sap, GCC_ATYP_ALIAS)) != NULL) { char *an = ga->sarg(0); char *sn = getsoname(sp); char *v; v = attr_find(sp->sap, GCC_ATYP_WEAK) ? "weak" : "globl"; printf("\t.%s %s\n", v, sn); printf("\t.set %s,%s\n", sn, an); } if (alias != NULL && (sp->sclass != PARAM)) { char *name = getexname(sp); printf("\t.globl %s\n", name); printf("%s = ", name); printf("%s\n", exname(alias)); alias = NULL; } if ((constructor || destructor) && (sp->sclass != PARAM)) { NODE *p = p1alloc(); p->n_op = NAME; p->n_sp = (struct symtab *)(constructor ? "constructor" : "destructor"); sp->sap = attr_add(sp->sap, gcc_attr_parse(p)); constructor = destructor = 0; } #endif }
static P1ND * import(P1ND *p) { struct attr *ap; P1ND *q; char *name; struct symtab *sp; name = getexname(p->n_sp); sp = picsymtab("__imp_", name, ""); q = xbcon(0, sp, PTR+VOID); q = block(UMUL, q, 0, PTR|VOID, 0, 0); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ p1nfree(p); return q; }
/* * Define everything needed to print out some data (or text). * This means segment, alignment, visibility, etc. */ void defloc(struct symtab *sp) { char *name; name = getexname(sp); if (sp->sclass == EXTDEF) { printf("\t.globl %s\n", name); if (ISFTN(sp->stype)) { printf("\t.type %s,@function\n", name); } else { printf("\t.type %s,@object\n", name); printf("\t.size %s,%d\n", name, (int)tsize(sp->stype, sp->sdf, sp->sap)/SZCHAR); } } if (sp->slevel == 0) printf("%s:\n", name); else printf(LABFMT ":\n", sp->soffset); }
/* make a common declaration for id, if reasonable */ void defzero(struct symtab *sp) { int off, al; char *name; name = getexname(sp); off = tsize(sp->stype, sp->sdf, sp->sap); SETOFF(off,SZCHAR); off /= SZCHAR; al = talign(sp->stype, sp->sap)/SZCHAR; if (sp->sclass == STATIC) { if (sp->slevel == 0) { printf("\t.local %s\n", name); } else printf("\t.local " LABFMT "\n", sp->soffset); } if (sp->slevel == 0) { printf("\t.comm %s,0%o,%d\n", name, off, al); } else printf("\t.comm " LABFMT ",0%o,%d\n", sp->soffset, off, al); }
/* * Define everything needed to print out some data (or text). * This means segment, alignment, visibility, etc. */ void defloc(struct symtab *sp) { char *n; if (ISFTN(sp->stype)) return; /* XXX until fixed */ n = getexname(sp); if (sp->sclass == EXTDEF) printf(" .globl %s\n", n); if (sp->slevel == 0) { #ifdef USE_GAS printf("\t.type %s,@%s\n", n, ISFTN(sp->stype) ? "function" : "object"); if (!ISFTN(sp->stype)) printf("\t.size %s," CONFMT "\n", n, tsize(sp->stype, sp->sdf, sp->sap)); #endif printf("%s:\n", n); } else printf(LABFMT ":\n", sp->soffset); }
/* * Create a reference for a static variable. */ static P1ND * picstatic(P1ND *p) { #if defined(ELFABI) P1ND *q, *r; struct symtab *sp; q = tempnode(gotnr, PTR|VOID, 0, 0); if (p->n_sp->slevel > 0) { char buf[32]; if ((p->n_sp->sflags & SMASK) == SSTRING) p->n_sp->sflags |= SASG; snprintf(buf, 32, LABFMT, (int)p->n_sp->soffset); sp = picsymtab("", buf, "@GOTOFF"); } else sp = picsymtab("", getsoname(p->n_sp), "@GOTOFF"); sp->sclass = STATIC; sp->stype = p->n_sp->stype; r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ p1nfree(p); return q; #elif defined(MACHOABI) P1ND *q, *r; struct symtab *sp; char buf2[256]; snprintf(buf2, 256, "-L%s$pb", cftnsp->soname ? cftnsp->soname : cftnsp->sname); if (p->n_sp->slevel > 0) { char buf1[32]; snprintf(buf1, 32, LABFMT, (int)p->n_sp->soffset); sp = picsymtab("", buf1, buf2); } else { char *name = getexname(p->n_sp); sp = picsymtab("", name, buf2); } sp->sclass = STATIC; sp->stype = p->n_sp->stype; q = tempnode(gotnr, PTR+VOID, 0, 0); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; p1nfree(p); return q; #else /* defined(PECOFFABI) || defined(AOUTABI) */ return p; #endif }
/* * Create a reference for an extern variable. */ static P1ND * picext(P1ND *p) { struct attr *ap; #if defined(ELFABI) P1ND *q, *r; struct symtab *sp; char *name; q = tempnode(gotnr, PTR|VOID, 0, 0); name = getexname(p->n_sp); #ifdef GCC_COMPAT if ((ap = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) && strcmp(ap->sarg(0), "hidden") == 0) { /* For hidden vars use GOTOFF */ sp = picsymtab("", name, "@GOTOFF"); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ p1nfree(p); return q; } #endif sp = picsymtab("", name, "@GOT"); #ifdef GCC_COMPAT if (attr_find(p->n_sp->sap, GCC_ATYP_STDCALL) != NULL) p->n_sp->sflags |= SSTDCALL; #endif sp->sflags = p->n_sp->sflags & SSTDCALL; sp->sap = attr_add(p->n_sp->sap, sp->sap); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); q = block(UMUL, q, 0, PTR|VOID, 0, 0); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ p1nfree(p); return q; #elif defined(MACHOABI) P1ND *q, *r; struct symtab *sp; char buf2[256], *name, *pspn; name = getsoname(cftnsp); pspn = getexname(p->n_sp); if (p->n_sp->sclass == EXTDEF) { snprintf(buf2, 256, "-L%s$pb", name); sp = picsymtab("", pspn, buf2); } else { snprintf(buf2, 256, "$non_lazy_ptr-L%s$pb", name); sp = picsymtab("L", pspn, buf2); addstub(&nlplist, pspn); } sp->stype = p->n_sp->stype; q = tempnode(gotnr, PTR+VOID, 0, 0); r = xbcon(0, sp, INT); q = buildtree(PLUS, q, r); if (p->n_sp->sclass != EXTDEF) q = block(UMUL, q, 0, PTR+VOID, 0, 0); q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap); q->n_sp = p->n_sp; /* for init */ p1nfree(p); return q; #else /* defined(PECOFFABI) || defined(AOUTABI) */ return p; #endif }