Example #1
0
/*
 * 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;
}
Example #2
0
static NODE *
picstatic(NODE *p)
{
	NODE *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, "@GOT");
	} else {
		sp = picsymtab("", getsoname(p->n_sp), "@GOT");
	}
	
	sp->sclass = STATIC;
	sp->stype = p->n_sp->stype;
	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;
}
Example #3
0
/*
 * 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
}
Example #4
0
static P1ND *
tlsnonpic(P1ND *p)
{
	P1ND *q, *r;
	struct symtab *sp, *sp2;
	int ext = p->n_sp->sclass;
	char *name;

	name = getsoname(p->n_sp);
	sp = picsymtab("", name,
	    ext == EXTERN ? "@INDNTPOFF" : "@NTPOFF");
	q = xbcon(0, sp, INT);
	if (ext == EXTERN)
		q = block(UMUL, q, NIL, PTR|VOID, 0, 0);

	sp2 = lookup("%gs:0", 0);
	sp2->stype = EXTERN|INT;
	r = nametree(sp2);

	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;
}
Example #5
0
/*
 * 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;

	c = p->n_sp->soname ? p->n_sp->soname : exname(p->n_sp->sname);
	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
}
Example #6
0
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;
}
Example #7
0
void
myp2tree(NODE *p)
{
	struct symtab *sp;
	NODE *l;

	if (cdope(p->n_op) & CALLFLG) {
		if (p->n_left->n_op == ADDROF &&
		    p->n_left->n_left->n_op == NAME) {
			p->n_left = nfree(p->n_left);
			l = p->n_left;
			l->n_op = ICON;
			if (l->n_sp->sclass != STATIC &&
			    l->n_sp->sclass != USTATIC)
				l->n_sp =
				    picsymtab(l->n_sp->sname, "@PLTPC", "");
		}
	}

	if (p->n_op != FCON)
		return;

	sp = IALLOC(sizeof(struct symtab));
	sp->sclass = STATIC;
	sp->sap = 0;
	sp->slevel = 1; /* fake numeric label */
	sp->soffset = getlab();
	sp->sflags = 0;
	sp->stype = p->n_type;
	sp->squal = (CON >> TSHIFT);
	sp->sname = NULL;

	locctr(DATA, sp);
	defloc(sp);
	ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);

	p->n_op = NAME;
	slval(p, 0);
	p->n_sp = sp;

}
Example #8
0
/*
 * Create a reference for a TLS variable.
 */
static P1ND *
tlspic(P1ND *p)
{
	P1ND *q, *r;
	struct symtab *sp, *sp2;
	char *name;

	/*
	 * creates:
	 *   leal var@TLSGD(%ebx),%eax
	 *   call ___tls_get_addr@PLT
	 */

	/* calc address of var@TLSGD */
	q = tempnode(gotnr, PTR|VOID, 0, 0);
	name = getsoname(p->n_sp);
	sp = picsymtab("", name, "@TLSGD");
	r = xbcon(0, sp, INT);
	q = buildtree(PLUS, q, r);

	/* assign to %eax */
	r = block(REG, NIL, NIL, PTR|VOID, 0, 0);
	r->n_rval = EAX;
	q = buildtree(ASSIGN, r, q);

	/* call ___tls_get_addr */
	sp2 = lookup("___tls_get_addr@PLT", 0);
	sp2->stype = EXTERN|INT|FTN;
	r = nametree(sp2);
	r = buildtree(ADDROF, r, NIL);
	r = block(UCALL, r, NIL, INT, 0, 0);

	/* fusion both parts together */
	q = buildtree(COMOP, 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;
}
Example #9
0
/*
 * 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

}
Example #10
0
/*
 * 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

}