]> Cypherpunks repositories - gostls13.git/commitdiff
ld: weak symbols
authorRuss Cox <rsc@golang.org>
Thu, 24 Feb 2011 21:45:45 +0000 (16:45 -0500)
committerRuss Cox <rsc@golang.org>
Thu, 24 Feb 2011 21:45:45 +0000 (16:45 -0500)
A reference to the address of weak.foo resolves at link time
to the address of the symbol foo if foo would end up in the
binary anyway, or to zero if foo would not be in the binary.

For example:

        int xxx = 1;
        int yyy = 2;
        int weak·xxx;
        int weak·yyy;

        void main·main(void) {
                runtime·printf("%p %p %p\n", &xxx, &weak·xxx, &weak·yyy);
        }

prints the same non-nil address twice, then 0 (because yyy is not
referenced so it was dropped from the binary).

This will be used by the reflection tables.

R=iant
CC=golang-dev
https://golang.org/cl/4223044

src/cmd/5l/obj.c
src/cmd/5l/pass.c
src/cmd/6l/obj.c
src/cmd/6l/pass.c
src/cmd/8l/obj.c
src/cmd/8l/pass.c
src/cmd/ld/go.c
src/cmd/ld/lib.c
src/cmd/ld/lib.h

index c929b3291ea6baaa8a3ea166c45d2b0693366a67..f252f9fc562035cdf803f604911f12d7087cc94b 100644 (file)
@@ -280,6 +280,7 @@ main(int argc, char *argv[])
        symtab();
        dodata();
        address();
+       doweak();
        reloc();
        asmb();
        undef();
index e16b34171be85301496d2ee041be6c751dc59539..7e1ba6a09a1bc31d08cdbe99db2d7f65f6f4c363 100644 (file)
 
 static void xfol(Prog*, Prog**);
 
-void
-undef(void)
-{
-       int i;
-       Sym *s;
-
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash)
-               if(s->type == SXREF)
-                       diag("%s: not defined", s->name);
-}
-
 Prog*
 brchain(Prog *p)
 {
index 8d602b649f83a06f68c840a4f294d788fb9a3988..f113e3ec1e2fd51931647209a8bc5e27175e0fa3 100644 (file)
@@ -267,6 +267,7 @@ main(int argc, char *argv[])
        symtab();
        dodata();
        address();
+       doweak();
        reloc();
        asmb();
        undef();
index 98a32a7624241a17d462efd3054ab94efce8c02d..8fda943923aae75a7cc35f5d5ab190c877dd1e23 100644 (file)
@@ -718,15 +718,3 @@ atolwhex(char *s)
                n = -n;
        return n;
 }
-
-void
-undef(void)
-{
-       int i;
-       Sym *s;
-
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash)
-               if(s->type == SXREF)
-                       diag("%s: not defined", s->name);
-}
index 791ba1e525390c886d81f58ecb9a4e205c6618bd..d505dc10e507218017d731552b271e7469dc2534 100644 (file)
@@ -316,6 +316,7 @@ main(int argc, char *argv[])
        symtab();
        dodata();
        address();
+       doweak();
        reloc();
        asmb();
        undef();
index bbb86cff7da10ef69ed516ea039c5dfab78eb2a7..294926f2937442fbb7d4940814be539998e3e773 100644 (file)
@@ -666,15 +666,3 @@ atolwhex(char *s)
                n = -n;
        return n;
 }
-
-void
-undef(void)
-{
-       int i;
-       Sym *s;
-
-       for(i=0; i<NHASH; i++)
-       for(s = hash[i]; s != S; s = s->hash)
-               if(s->type == SXREF)
-                       diag("%s(%d): not defined", s->name, s->version);
-}
index 2c6a6d084b641a93ba5d32052db270702b9dc262..2f5d31e515445c0affc3fc96551eaeadaba1c8c4 100644 (file)
@@ -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,35 @@ 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->value = 0;
+                       continue;
+               }
+       }
 }
 
 void
index 39593085d4507ff4e3b64d2132143b99a5ee85ae..e645502b33840f30f42759fb3e41cbb249902753 100644 (file)
@@ -1279,3 +1279,15 @@ headtype(char *name)
        errorexit();
        return -1;  // not reached
 }
+
+void
+undef(void)
+{
+       int i;
+       Sym *s;
+
+       for(i=0; i<NHASH; i++)
+       for(s = hash[i]; s != S; s = s->hash)
+               if(s->type == SXREF)
+                       diag("%s(%d): not defined", s->name, s->version);
+}
index 7df348353cb4f5aedd82d112ebbf38a14eff5d0c..adde2c9ff2a4980f82d3e6c3bea0e8543b6da8b0 100644 (file)
@@ -167,6 +167,8 @@ int archreloc(Reloc*, Sym*, vlong*);
 void   adddynsym(Sym*);
 void   addexport(void);
 void   dostkcheck(void);
+void   undef(void);
+void   doweak(void);
 
 int    pathchar(void);
 void*  mal(uint32);