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