ref: 0d87019a9b5479ed2d5ce13b9bfe774c395b9669
parent: c727d2ae8a3a828649e34c71aa45b6665b1a8328
author: cinap_lenrek <[email protected]>
date: Sun May 24 21:57:18 EDT 2015
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.
--- a/sys/src/cmd/cc/dcl.c
+++ b/sys/src/cmd/cc/dcl.c
@@ -1571,8 +1571,6 @@
stkoff = maxround(stkoff, autoffset);
symadjust(s, n, v - s->offset);
}
- if(w <= ewidth[TIND])
- goto no;
if(n->op == OAS)
diag(Z, "oops in contig");
/*ZZZ this appears incorrect
@@ -1585,8 +1583,58 @@
if(n->left->type)
if(n->left->type->width == w)
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
*
@@ -1597,15 +1645,12 @@
} while(*(long**)&X);
*/
- for(q=n; q->op != ONAME; q=q->left)
- ;
-
zt = ewidth[TIND] > ewidth[TLONG]? types[TVLONG]: types[TLONG];
p = new(ONAME, Z, Z);
*p = *q;
p->type = typ(TIND, zt);
- p->xoffset = s->offset;
+ p->xoffset = v;
r = new(ONAME, Z, Z);
*r = *p;