commit 433adcd26eaa7d73aaa761abfabc90c3e850e41e
parent 178f43cfd06bac8c689e70a66dfd63cc10347ceb
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 13 Nov 2021 16:50:02 +0100
cc1: Emit padding bytes
Types have alignment that we were ignoring when we were
emitting constants, that was making that the data didn't
match correctly the layout of the desired output.
Diffstat:
2 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/include/scc/scc/scc.h b/include/scc/scc/scc.h
@@ -15,6 +15,7 @@ extern int enadebug;
#define TUINT_MAX ULLONG_MAX
#define TINT_MAX LLONG_MAX
#define TFLOAT double
+#define SIZET size_t
struct items {
char **s;
diff --git a/src/cmd/cc/cc1/code.c b/src/cmd/cc/cc1/code.c
@@ -335,14 +335,36 @@ emitstring(Symbol *sym, Type *tp)
}
}
+static Node *
+zeronode(Type *tp)
+{
+ return simplify(convert(constnode(zero), tp, 0));
+}
+
+static int
+emitpadding(Type *tp, SIZET *addr)
+{
+ SIZET n;
+ int i;
+
+ n = *addr & tp->align-1;
+ for (i = 0; i < n; i++)
+ emitexp(OEXPR, zeronode(chartype));
+ *addr += n;
+
+ return n;
+}
+
static void
-emitdesig(Node *np, Type *tp)
+emitdesig(Node *np, Type *tp, SIZET *addr)
{
Symbol *sym;
- size_t n; /* TODO: This should be SIZET */
+ SIZET n;
Node *aux;
Type *p;
+ emitpadding(tp, addr);
+
if (!np) {
sym = NULL;
} else {
@@ -351,6 +373,7 @@ emitdesig(Node *np, Type *tp)
sym = np->sym;
if (sym->flags & SSTRING) {
emitstring(sym, tp);
+ *addr += tp->n.elem;
return;
}
if ((sym->flags & SINITLST) == 0)
@@ -361,24 +384,23 @@ emitdesig(Node *np, Type *tp)
case PTR:
case INT:
case ENUM:
- if (sym)
- aux = *sym->u.init;
- else
- aux = simplify(convert(constnode(zero), tp, 0));
+ aux = sym ? *sym->u.init : zeronode(tp);
+ *addr += aux->type->size;
emitexp(OEXPR, aux);
break;
case UNION:
- n = tp->n.elem-1;
aux = (sym) ? sym->u.init[0] : NULL;
- emitdesig(aux, aux->type);
+ emitdesig(aux, aux->type, addr);
+ emitpadding(tp, addr);
break;
case STRUCT:
case ARY:
for (n = 0; n < tp->n.elem; ++n) {
aux = (sym) ? sym->u.init[n] : NULL;
p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type;
- emitdesig(aux, p);
+ emitdesig(aux, p, addr);
}
+ emitpadding(tp, addr);
break;
default:
abort();
@@ -399,9 +421,10 @@ static void
emitinit(int op, void *arg)
{
Node *np = arg;
+ SIZET addr = 0;
fputs("\t(\n", outfp);
- emitdesig(np, np->type);
+ emitdesig(np, np->type, &addr);
fputs(")\n", outfp);
}