summaryrefslogtreecommitdiff
path: root/src/cmd/ld/go.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/ld/go.c')
-rw-r--r--src/cmd/ld/go.c33
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