1
0
mirror of https://github.com/golang/go synced 2024-11-19 17:04:41 -07:00

ld: weak symbols

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
This commit is contained in:
Russ Cox 2011-02-24 16:45:45 -05:00
parent 4185a9e2b2
commit d94bf76239
9 changed files with 48 additions and 36 deletions

View File

@ -280,6 +280,7 @@ main(int argc, char *argv[])
symtab();
dodata();
address();
doweak();
reloc();
asmb();
undef();

View File

@ -35,18 +35,6 @@
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)
{

View File

@ -267,6 +267,7 @@ main(int argc, char *argv[])
symtab();
dodata();
address();
doweak();
reloc();
asmb();
undef();

View 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);
}

View File

@ -316,6 +316,7 @@ main(int argc, char *argv[])
symtab();
dodata();
address();
doweak();
reloc();
asmb();
undef();

View 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);
}

View 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

View 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);
}

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