diff options
Diffstat (limited to 'src/cmd/ld/go.c')
-rw-r--r-- | src/cmd/ld/go.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/src/cmd/ld/go.c b/src/cmd/ld/go.c index 2c6a6d084..3c1e230b4 100644 --- a/src/cmd/ld/go.c +++ b/src/cmd/ld/go.c @@ -550,6 +550,8 @@ mark(Sym *s) if(s == S || s->reachable) return; + if(strncmp(s->name, "weak.", 5) == 0) + return; s->reachable = 1; if(s->text) marktext(s); @@ -654,6 +656,37 @@ deadcode(void) textp = nil; else last->next = nil; + + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->hash) + if(strncmp(s->name, "weak.", 5) == 0) { + s->special = 1; // do not lay out in data segment + s->reachable = 1; + } +} + +void +doweak(void) +{ + int i; + Sym *s, *t; + + // resolve weak references only if + // target symbol will be in binary anyway. + for(i=0; i<NHASH; i++) + for(s = hash[i]; s != S; s = s->hash) { + if(strncmp(s->name, "weak.", 5) == 0) { + t = lookup(s->name+5, s->version); + if(t->type != 0 && t->reachable) { + s->value = t->value; + s->type = t->type; + } else { + s->type = SCONST; + s->value = 0; + } + continue; + } + } } void |