shithub: scc

Download patch

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);
 }