cc: handle unaligned data in = {0} local initializer

the emited code that initializes local variables did not handle
unaligned data causing stack corruption, affecting code like:

void main(void)
{
	char a[9] = {0};
}

this change will emit code that does byte stores for the unaligned
bytes and also handles small objects (<= 16 bytes) without branches.
This commit is contained in:
cinap_lenrek 2015-05-25 01:57:18 +02:00
parent c727d2ae8a
commit 0d87019a9b

View file

@ -1571,8 +1571,6 @@ contig(Sym *s, Node *n, long v)
stkoff = maxround(stkoff, autoffset); stkoff = maxround(stkoff, autoffset);
symadjust(s, n, v - s->offset); symadjust(s, n, v - s->offset);
} }
if(w <= ewidth[TIND])
goto no;
if(n->op == OAS) if(n->op == OAS)
diag(Z, "oops in contig"); diag(Z, "oops in contig");
/*ZZZ this appears incorrect /*ZZZ this appears incorrect
@ -1585,8 +1583,58 @@ if not, bail
if(n->left->type) if(n->left->type)
if(n->left->type->width == w) if(n->left->type->width == w)
goto no; goto no;
while(w & (ewidth[TIND]-1))
w++; for(q=n; q->op != ONAME; q=q->left)
;
v = s->offset;
/* unaligned front */
while(w > 0 && (v % ewidth[TIND]) != 0){
p = new(ONAME, Z, Z);
*p = *q;
if(w >= ewidth[TLONG] && (v % ewidth[TLONG]) == 0)
p->type = types[TLONG];
else
p->type = types[TCHAR];
p->xoffset = v;
v += p->type->width;
w -= p->type->width;
m = new(OCONST, Z, Z);
m->vconst = 0;
m->type = p->type;
r = new(OAS, p, m);
n = new(OLIST, r, n);
}
/* unaligned (or small) back */
while(w > 0 && ((w % ewidth[TIND]) != 0 || w <= 16)){
p = new(ONAME, Z, Z);
*p = *q;
if(w >= ewidth[TLONG] && (w % ewidth[TLONG]) == 0)
p->type = types[TLONG];
else
p->type = types[TCHAR];
w -= p->type->width;
p->xoffset = v + w;
m = new(OCONST, Z, Z);
m->vconst = 0;
m->type = p->type;
r = new(OAS, p, m);
n = new(OLIST, r, n);
}
if(w == 0)
goto no;
/* /*
* insert the following code, where long becomes vlong if pointers are fat * insert the following code, where long becomes vlong if pointers are fat
* *
@ -1597,15 +1645,12 @@ if not, bail
} while(*(long**)&X); } while(*(long**)&X);
*/ */
for(q=n; q->op != ONAME; q=q->left)
;
zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG]; zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
p = new(ONAME, Z, Z); p = new(ONAME, Z, Z);
*p = *q; *p = *q;
p->type = typ(TIND, zt); p->type = typ(TIND, zt);
p->xoffset = s->offset; p->xoffset = v;
r = new(ONAME, Z, Z); r = new(ONAME, Z, Z);
*r = *p; *r = *p;