commit b36e3b65309bdaa5515cb2d9a6313998e174e35d
parent 6ac1bf55142759cdd9837f9c11103d1b0e4e15f7
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);
}