ref: b36e3b65309bdaa5515cb2d9a6313998e174e35d
parent: 6ac1bf55142759cdd9837f9c11103d1b0e4e15f7
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Sat Nov 13 11:50:02 EST 2021
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.
--- a/include/scc/scc/scc.h
+++ b/include/scc/scc/scc.h
@@ -15,6 +15,7 @@
#define TUINT_MAX ULLONG_MAX
#define TINT_MAX LLONG_MAX
#define TFLOAT double
+#define SIZET size_t
struct items {
char **s;
--- a/src/cmd/cc/cc1/code.c
+++ b/src/cmd/cc/cc1/code.c
@@ -335,14 +335,36 @@
}
}
+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 @@
sym = np->sym;
if (sym->flags & SSTRING) {
emitstring(sym, tp);
+ *addr += tp->n.elem;
return;
}
if ((sym->flags & SINITLST) == 0)
@@ -361,16 +384,14 @@
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:
@@ -377,8 +398,9 @@
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 @@
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);
}