scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

commit 472db47491cbcf7f61791775e7d81af0d023d0f8
parent fa420983bd4538a1b7ce8b63c091c1c621510469
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon, 11 Feb 2019 16:56:09 +0000

[ld] Add handle of common blocks

Diffstat:
Msrc/cmd/ld/main.c | 20+++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/src/cmd/ld/main.c b/src/cmd/ld/main.c @@ -37,6 +37,7 @@ struct symbol { char *name; Obj *obj; Objsym *def; + unsigned long long size, value; struct symbol *next, *prev; struct symbol *hash; }; @@ -127,6 +128,8 @@ lookup(char *name, int install) 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,13 +144,15 @@ define(Objsym *osym, Obj *obj) { Symbol *sym = lookup(osym->name, INSTALL); - if (sym->obj) { + if (sym->def && sym->def->type != 'C') { error("%s: symbol redefined", osym->name); return NULL; } 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,12 +164,25 @@ define(Objsym *osym, Obj *obj) 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)) define(osym, obj);