shithub: scc

Download patch

ref: 6ee2fb85da693eb56401f7b87b551d26577410aa
parent: e12a1007fa3b9df81e20951314a1fc93f0707382
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Mon Feb 11 11:56:09 EST 2019

[ld] Add handle of common blocks

--- a/src/cmd/ld/main.c
+++ b/src/cmd/ld/main.c
@@ -37,6 +37,7 @@
 	char *name;
 	Obj *obj;
 	Objsym *def;
+	unsigned long long size, value;
 	struct symbol *next, *prev;
 	struct symbol *hash;
 };
@@ -127,6 +128,8 @@
 	sym->name = memcpy(s, name, len);
 	sym->hash = symtab[h];
 	symtab[h] = sym;
+	sym->value = 0;
+	sym->size = 0;
 
 	refhead.next->prev = sym;
 	sym->next = refhead.next;
@@ -141,7 +144,7 @@
 {
 	Symbol *sym = lookup(osym->name, INSTALL);
 
-	if (sym->obj) {
+	if (sym->def && sym->def->type != 'C') {
 		error("%s: symbol redefined", osym->name);
 		return NULL;
 	}
@@ -148,6 +151,8 @@
 
 	sym->obj = obj;
 	sym->def = osym;
+	sym->size = osym->size;
+	sym->value = osym->value;
 
 	sym->next->prev = sym->prev;
 	sym->prev->next = sym->next;
@@ -159,11 +164,24 @@
 static int
 newsym(Objsym *osym, void *obj)
 {
+	Symbol *sym;
+
 	switch (osym->type) {
 	case 'U':
 		lookup(osym->name, INSTALL);
 	case '?':
 	case 'N':
+		break;
+	case 'C':
+		sym = lookup(osym->name, NOINSTALL);
+		if (!sym || !sym->def) {
+			define(osym, obj);
+			break;
+		}
+		if (sym->def->type != 'C')
+			break;
+		if (sym->size < osym->size)
+			sym->size = osym->size;
 		break;
 	default:
 		if (isupper(osym->type))