Commit d37c572a authored by Russ Cox's avatar Russ Cox

cmd/ld: move symtab, ELF generation to portable code

More cleanup in preparation for fixing issue 4069.

This CL replaces the three nearly identical copies of the
asmb ELF code with a single asmbelf function in elf.c.

In addition to the ELF code movement, remove the elfstr
array in favor of a simpler lookup, and identify sections by
name throughout instead of computing fragile indices.

The CL also replaces the three nearly identical copies of the
genasmsym code with a single genasmsym function in lib.c.

The ARM linker still compiles and generates binaries,
but I haven't tested the binaries. They may not work.

R=ken2
CC=golang-dev
https://golang.org/cl/7062047
parent b006cd9b
This diff is collapsed.
...@@ -145,6 +145,7 @@ struct Sym ...@@ -145,6 +145,7 @@ struct Sym
int32 sig; int32 sig;
int32 size; int32 size;
int32 align; // if non-zero, required alignment in bytes int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
uchar special; uchar special;
uchar fnptr; // used as fn ptr uchar fnptr; // used as fn ptr
Sym* hash; // in hash table Sym* hash; // in hash table
...@@ -159,6 +160,7 @@ struct Sym ...@@ -159,6 +160,7 @@ struct Sym
char* dynimpname; char* dynimpname;
char* dynimplib; char* dynimplib;
char* dynimpvers; char* dynimpvers;
struct Section* sect;
// STEXT // STEXT
Auto* autom; Auto* autom;
......
...@@ -96,10 +96,15 @@ span(void) ...@@ -96,10 +96,15 @@ span(void)
Bprint(&bso, "%5.2f span\n", cputime()); Bprint(&bso, "%5.2f span\n", cputime());
Bflush(&bso); Bflush(&bso);
sect = addsection(&segtext, ".text", 05);
lookup("text", 0)->sect = sect;
lookup("etext", 0)->sect = sect;
bflag = 0; bflag = 0;
c = INITTEXT; c = INITTEXT;
otxt = c; otxt = c;
for(cursym = textp; cursym != nil; cursym = cursym->next) { for(cursym = textp; cursym != nil; cursym = cursym->next) {
cursym->sect = sect;
p = cursym->text; p = cursym->text;
if(p == P || p->link == P) { // handle external functions and ELF section symbols if(p == P || p->link == P) { // handle external functions and ELF section symbols
if(cursym->type & SSUB) if(cursym->type & SSUB)
...@@ -254,7 +259,6 @@ span(void) ...@@ -254,7 +259,6 @@ span(void)
} }
} }
} }
sect = addsection(&segtext, ".text", 05);
sect->vaddr = INITTEXT; sect->vaddr = INITTEXT;
sect->len = c - INITTEXT; sect->len = c - INITTEXT;
} }
......
This diff is collapsed.
...@@ -153,6 +153,7 @@ struct Sym ...@@ -153,6 +153,7 @@ struct Sym
int32 plt; int32 plt;
int32 got; int32 got;
int32 align; // if non-zero, required alignment in bytes int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
Sym* hash; // in hash table Sym* hash; // in hash table
Sym* allsym; // in all symbol list Sym* allsym; // in all symbol list
Sym* next; // in text or data list Sym* next; // in text or data list
...@@ -167,6 +168,7 @@ struct Sym ...@@ -167,6 +168,7 @@ struct Sym
char* dynimpname; char* dynimpname;
char* dynimplib; char* dynimplib;
char* dynimpvers; char* dynimpvers;
struct Section* sect;
// STEXT // STEXT
Auto* autom; Auto* autom;
......
This diff is collapsed.
...@@ -137,6 +137,7 @@ struct Sym ...@@ -137,6 +137,7 @@ struct Sym
int32 plt; int32 plt;
int32 got; int32 got;
int32 align; // if non-zero, required alignment in bytes int32 align; // if non-zero, required alignment in bytes
int32 elfsym;
Sym* hash; // in hash table Sym* hash; // in hash table
Sym* allsym; // in all symbol list Sym* allsym; // in all symbol list
Sym* next; // in text or data list Sym* next; // in text or data list
...@@ -149,6 +150,7 @@ struct Sym ...@@ -149,6 +150,7 @@ struct Sym
char* dynimpname; char* dynimpname;
char* dynimplib; char* dynimplib;
char* dynimpvers; char* dynimpvers;
struct Section* sect;
// STEXT // STEXT
Auto* autom; Auto* autom;
......
...@@ -982,7 +982,8 @@ dodata(void) ...@@ -982,7 +982,8 @@ dodata(void)
/* skip symbols belonging to segtext */ /* skip symbols belonging to segtext */
s = datap; s = datap;
for(; s != nil && s->type < SELFSECT; s = s->next); for(; s != nil && s->type < SELFSECT; s = s->next)
;
/* writable ELF sections */ /* writable ELF sections */
datsize = 0; datsize = 0;
...@@ -991,6 +992,7 @@ dodata(void) ...@@ -991,6 +992,7 @@ dodata(void)
if(s->align != 0) if(s->align != 0)
datsize = rnd(datsize, s->align); datsize = rnd(datsize, s->align);
sect->vaddr = datsize; sect->vaddr = datsize;
s->sect = sect;
s->type = SDATA; s->type = SDATA;
s->value = datsize; s->value = datsize;
datsize += rnd(s->size, PtrSize); datsize += rnd(s->size, PtrSize);
...@@ -1000,7 +1002,10 @@ dodata(void) ...@@ -1000,7 +1002,10 @@ dodata(void)
/* pointer-free data */ /* pointer-free data */
sect = addsection(&segdata, ".noptrdata", 06); sect = addsection(&segdata, ".noptrdata", 06);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("noptrdata", 0)->sect = sect;
lookup("enoptrdata", 0)->sect = sect;
for(; s != nil && s->type < SDATA; s = s->next) { for(; s != nil && s->type < SDATA; s = s->next) {
s->sect = sect;
s->type = SDATA; s->type = SDATA;
t = alignsymsize(s->size); t = alignsymsize(s->size);
datsize = aligndatsize(datsize, s); datsize = aligndatsize(datsize, s);
...@@ -1013,7 +1018,10 @@ dodata(void) ...@@ -1013,7 +1018,10 @@ dodata(void)
/* data */ /* data */
sect = addsection(&segdata, ".data", 06); sect = addsection(&segdata, ".data", 06);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("data", 0)->sect = sect;
lookup("edata", 0)->sect = sect;
for(; s != nil && s->type < SBSS; s = s->next) { for(; s != nil && s->type < SBSS; s = s->next) {
s->sect = sect;
s->type = SDATA; s->type = SDATA;
t = alignsymsize(s->size); t = alignsymsize(s->size);
datsize = aligndatsize(datsize, s); datsize = aligndatsize(datsize, s);
...@@ -1030,7 +1038,10 @@ dodata(void) ...@@ -1030,7 +1038,10 @@ dodata(void)
/* bss */ /* bss */
sect = addsection(&segdata, ".bss", 06); sect = addsection(&segdata, ".bss", 06);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("bss", 0)->sect = sect;
lookup("ebss", 0)->sect = sect;
for(; s != nil && s->type < SNOPTRBSS; s = s->next) { for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
s->sect = sect;
t = alignsymsize(s->size); t = alignsymsize(s->size);
datsize = aligndatsize(datsize, s); datsize = aligndatsize(datsize, s);
s->value = datsize; s->value = datsize;
...@@ -1046,26 +1057,33 @@ dodata(void) ...@@ -1046,26 +1057,33 @@ dodata(void)
/* pointer-free bss */ /* pointer-free bss */
sect = addsection(&segdata, ".noptrbss", 06); sect = addsection(&segdata, ".noptrbss", 06);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("noptrbss", 0)->sect = sect;
lookup("enoptrbss", 0)->sect = sect;
for(; s != nil; s = s->next) { for(; s != nil; s = s->next) {
if(s->type > SNOPTRBSS) { if(s->type > SNOPTRBSS) {
cursym = s; cursym = s;
diag("unexpected symbol type %d", s->type); diag("unexpected symbol type %d", s->type);
} }
s->sect = sect;
t = alignsymsize(s->size); t = alignsymsize(s->size);
datsize = aligndatsize(datsize, s); datsize = aligndatsize(datsize, s);
s->value = datsize; s->value = datsize;
datsize += t; datsize += t;
} }
sect->len = datsize - sect->vaddr; sect->len = datsize - sect->vaddr;
lookup("end", 0)->sect = sect;
/* we finished segdata, begin segtext */ /* we finished segdata, begin segtext */
/* read-only data */ /* read-only data */
sect = addsection(&segtext, ".rodata", 04); sect = addsection(&segtext, ".rodata", 04);
sect->vaddr = 0; sect->vaddr = 0;
lookup("rodata", 0)->sect = sect;
lookup("erodata", 0)->sect = sect;
datsize = 0; datsize = 0;
s = datap; s = datap;
for(; s != nil && s->type < STYPELINK; s = s->next) { for(; s != nil && s->type < STYPELINK; s = s->next) {
s->sect = sect;
if(s->align != 0) if(s->align != 0)
datsize = rnd(datsize, s->align); datsize = rnd(datsize, s->align);
s->type = SRODATA; s->type = SRODATA;
...@@ -1078,7 +1096,10 @@ dodata(void) ...@@ -1078,7 +1096,10 @@ dodata(void)
/* type */ /* type */
sect = addsection(&segtext, ".typelink", 04); sect = addsection(&segtext, ".typelink", 04);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("typelink", 0)->sect = sect;
lookup("etypelink", 0)->sect = sect;
for(; s != nil && s->type == STYPELINK; s = s->next) { for(; s != nil && s->type == STYPELINK; s = s->next) {
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += s->size; datsize += s->size;
...@@ -1089,7 +1110,10 @@ dodata(void) ...@@ -1089,7 +1110,10 @@ dodata(void)
/* gcdata */ /* gcdata */
sect = addsection(&segtext, ".gcdata", 04); sect = addsection(&segtext, ".gcdata", 04);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("gcdata", 0)->sect = sect;
lookup("egcdata", 0)->sect = sect;
for(; s != nil && s->type == SGCDATA; s = s->next) { for(; s != nil && s->type == SGCDATA; s = s->next) {
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += s->size; datsize += s->size;
...@@ -1100,7 +1124,10 @@ dodata(void) ...@@ -1100,7 +1124,10 @@ dodata(void)
/* gcbss */ /* gcbss */
sect = addsection(&segtext, ".gcbss", 04); sect = addsection(&segtext, ".gcbss", 04);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("gcbss", 0)->sect = sect;
lookup("egcbss", 0)->sect = sect;
for(; s != nil && s->type == SGCBSS; s = s->next) { for(; s != nil && s->type == SGCBSS; s = s->next) {
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += s->size; datsize += s->size;
...@@ -1111,7 +1138,10 @@ dodata(void) ...@@ -1111,7 +1138,10 @@ dodata(void)
/* gosymtab */ /* gosymtab */
sect = addsection(&segtext, ".gosymtab", 04); sect = addsection(&segtext, ".gosymtab", 04);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("symtab", 0)->sect = sect;
lookup("esymtab", 0)->sect = sect;
for(; s != nil && s->type < SPCLNTAB; s = s->next) { for(; s != nil && s->type < SPCLNTAB; s = s->next) {
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += s->size; datsize += s->size;
...@@ -1122,7 +1152,10 @@ dodata(void) ...@@ -1122,7 +1152,10 @@ dodata(void)
/* gopclntab */ /* gopclntab */
sect = addsection(&segtext, ".gopclntab", 04); sect = addsection(&segtext, ".gopclntab", 04);
sect->vaddr = datsize; sect->vaddr = datsize;
lookup("pclntab", 0)->sect = sect;
lookup("epclntab", 0)->sect = sect;
for(; s != nil && s->type < SELFROSECT; s = s->next) { for(; s != nil && s->type < SELFROSECT; s = s->next) {
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += s->size; datsize += s->size;
...@@ -1136,6 +1169,7 @@ dodata(void) ...@@ -1136,6 +1169,7 @@ dodata(void)
if(s->align != 0) if(s->align != 0)
datsize = rnd(datsize, s->align); datsize = rnd(datsize, s->align);
sect->vaddr = datsize; sect->vaddr = datsize;
s->sect = sect;
s->type = SRODATA; s->type = SRODATA;
s->value = datsize; s->value = datsize;
datsize += rnd(s->size, PtrSize); datsize += rnd(s->size, PtrSize);
...@@ -1158,9 +1192,12 @@ textaddress(void) ...@@ -1158,9 +1192,12 @@ textaddress(void)
// Could parallelize, by assigning to text // Could parallelize, by assigning to text
// and then letting threads copy down, but probably not worth it. // and then letting threads copy down, but probably not worth it.
sect = segtext.sect; sect = segtext.sect;
lookup("text", 0)->sect = sect;
lookup("etext", 0)->sect = sect;
va = INITTEXT; va = INITTEXT;
sect->vaddr = va; sect->vaddr = va;
for(sym = textp; sym != nil; sym = sym->next) { for(sym = textp; sym != nil; sym = sym->next) {
sym->sect = sect;
if(sym->type & SSUB) if(sym->type & SSUB)
continue; continue;
if(sym->align != 0) if(sym->align != 0)
......
This diff is collapsed.
...@@ -841,7 +841,8 @@ typedef struct { ...@@ -841,7 +841,8 @@ typedef struct {
* Section header. * Section header.
*/ */
typedef struct { typedef struct Elf64_Shdr Elf64_Shdr;
struct Elf64_Shdr {
Elf64_Word name; /* Section name (index into the Elf64_Word name; /* Section name (index into the
section header string table). */ section header string table). */
Elf64_Word type; /* Section type. */ Elf64_Word type; /* Section type. */
...@@ -853,7 +854,9 @@ typedef struct { ...@@ -853,7 +854,9 @@ typedef struct {
Elf64_Word info; /* Depends on section type. */ Elf64_Word info; /* Depends on section type. */
Elf64_Xword addralign; /* Alignment in bytes. */ Elf64_Xword addralign; /* Alignment in bytes. */
Elf64_Xword entsize; /* Size of each entry in section. */ Elf64_Xword entsize; /* Size of each entry in section. */
} Elf64_Shdr;
int shnum; /* section number, not stored on disk */
};
/* /*
* Program header. * Program header.
...@@ -957,7 +960,6 @@ typedef Elf64_Phdr ElfPhdr; ...@@ -957,7 +960,6 @@ typedef Elf64_Phdr ElfPhdr;
void elfinit(void); void elfinit(void);
ElfEhdr *getElfEhdr(void); ElfEhdr *getElfEhdr(void);
ElfShdr *newElfShstrtab(vlong);
ElfShdr *newElfShdr(vlong); ElfShdr *newElfShdr(vlong);
ElfPhdr *newElfPhdr(void); ElfPhdr *newElfPhdr(void);
uint32 elfwritehdr(void); uint32 elfwritehdr(void);
...@@ -974,23 +976,38 @@ extern int numelfshdr; ...@@ -974,23 +976,38 @@ extern int numelfshdr;
extern int iself; extern int iself;
extern int elfverneed; extern int elfverneed;
int elfinterp(ElfShdr*, uint64, uint64, char*); int elfinterp(ElfShdr*, uint64, uint64, char*);
int elfwriteinterp(vlong); int elfwriteinterp(void);
int elfnetbsdsig(ElfShdr*, uint64, uint64); int elfnetbsdsig(ElfShdr*, uint64, uint64);
int elfwritenetbsdsig(vlong); int elfwritenetbsdsig(void);
int elfopenbsdsig(ElfShdr*, uint64, uint64); int elfopenbsdsig(ElfShdr*, uint64, uint64);
int elfwriteopenbsdsig(vlong); int elfwriteopenbsdsig(void);
void addbuildinfo(char*); void addbuildinfo(char*);
int elfbuildinfo(ElfShdr*, uint64, uint64); int elfbuildinfo(ElfShdr*, uint64, uint64);
int elfwritebuildinfo(vlong); int elfwritebuildinfo(void);
void elfdynhash(void); void elfdynhash(void);
ElfPhdr* elfphload(Segment*); ElfPhdr* elfphload(Segment*);
ElfShdr* elfshbits(Section*); ElfShdr* elfshbits(Section*);
ElfShdr* elfshalloc(Section*);
ElfShdr* elfshname(char*);
ElfShdr* elfshreloc(Section*);
void elfsetstring(char*, int); void elfsetstring(char*, int);
void elfaddverneed(Sym*); void elfaddverneed(Sym*);
void elfemitreloc(void);
void shsym(ElfShdr*, Sym*);
void phsh(ElfPhdr*, ElfShdr*);
void doelf(void);
void elfsetupplt(void);
void dwarfaddshstrings(Sym*);
void dwarfaddelfheaders(void);
void asmbelf(vlong symo);
void asmbelfsetup(void);
extern char linuxdynld[];
extern char freebsddynld[];
extern char netbsddynld[];
extern char openbsddynld[];
EXTERN int elfstrsize; EXTERN int elfstrsize;
EXTERN char* elfstrdat; EXTERN char* elfstrdat;
EXTERN int elftextsh;
EXTERN int buildinfolen; EXTERN int buildinfolen;
/* /*
......
...@@ -815,6 +815,7 @@ doweak(void) ...@@ -815,6 +815,7 @@ doweak(void)
if(t && t->type != 0 && t->reachable) { if(t && t->type != 0 && t->reachable) {
s->value = t->value; s->value = t->value;
s->type = t->type; s->type = t->type;
s->outer = t;
} else { } else {
s->type = SCONST; s->type = SCONST;
s->value = 0; s->value = 0;
......
...@@ -1501,3 +1501,85 @@ cwrite(void *buf, int n) ...@@ -1501,3 +1501,85 @@ cwrite(void *buf, int n)
} }
coutpos += n; coutpos += n;
} }
void
genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
{
Auto *a;
Sym *s;
// These symbols won't show up in the first loop below because we
// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
s = lookup("text", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
s = lookup("etext", 0);
if(s->type == STEXT)
put(s, s->name, 'T', s->value, s->size, s->version, 0);
for(s=allsym; s!=S; s=s->allsym) {
if(s->hide)
continue;
switch(s->type&SMASK) {
case SCONST:
case SRODATA:
case SSYMTAB:
case SPCLNTAB:
case SDATA:
case SNOPTRDATA:
case SELFROSECT:
case SMACHOGOT:
case STYPE:
case SSTRING:
case SGOSTRING:
case SWINDOWS:
case SGCDATA:
case SGCBSS:
if(!s->reachable)
continue;
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
continue;
case SBSS:
case SNOPTRBSS:
if(!s->reachable)
continue;
if(s->np > 0)
diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special);
put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
continue;
case SFILE:
put(nil, s->name, 'f', s->value, 0, s->version, 0);
continue;
}
}
for(s = textp; s != nil; s = s->next) {
if(s->text == nil)
continue;
/* filenames first */
for(a=s->autom; a; a=a->link)
if(a->type == D_FILE)
put(nil, a->asym->name, 'z', a->aoffset, 0, 0, 0);
else
if(a->type == D_FILE1)
put(nil, a->asym->name, 'Z', a->aoffset, 0, 0, 0);
put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
/* frame, auto and param after */
put(nil, ".frame", 'm', s->text->to.offset+PtrSize, 0, 0, 0);
for(a=s->autom; a; a=a->link)
if(a->type == D_AUTO)
put(nil, a->asym->name, 'a', -a->aoffset, 0, 0, a->gotype);
else
if(a->type == D_PARAM)
put(nil, a->asym->name, 'p', a->aoffset, 0, 0, a->gotype);
}
if(debug['v'] || debug['n'])
Bprint(&bso, "symsize = %ud\n", symsize);
Bflush(&bso);
}
...@@ -105,6 +105,7 @@ struct Section ...@@ -105,6 +105,7 @@ struct Section
uvlong len; uvlong len;
Section *next; // in segment list Section *next; // in segment list
Segment *seg; Segment *seg;
struct Elf64_Shdr *elfsect;
}; };
extern char symname[]; extern char symname[];
...@@ -133,6 +134,7 @@ EXTERN char* thestring; ...@@ -133,6 +134,7 @@ EXTERN char* thestring;
EXTERN int ndynexp; EXTERN int ndynexp;
EXTERN int havedynamic; EXTERN int havedynamic;
EXTERN int iscgo; EXTERN int iscgo;
EXTERN int elfglobalsymndx;
EXTERN char* tracksym; EXTERN char* tracksym;
EXTERN Segment segtext; EXTERN Segment segtext;
......
...@@ -82,10 +82,14 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other) ...@@ -82,10 +82,14 @@ putelfsyment(int off, vlong addr, vlong size, int info, int shndx, int other)
} }
} }
static int numelfsym = 1; // 0 is reserved
static int elfbind;
static void static void
putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
{ {
int bind, type, shndx, off; int bind, type, off;
Sym *xo;
USED(go); USED(go);
switch(t) { switch(t) {
...@@ -93,25 +97,37 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go) ...@@ -93,25 +97,37 @@ putelfsym(Sym *x, char *s, int t, vlong addr, vlong size, int ver, Sym *go)
return; return;
case 'T': case 'T':
type = STT_FUNC; type = STT_FUNC;
shndx = elftextsh + 0;
break; break;
case 'D': case 'D':
type = STT_OBJECT; type = STT_OBJECT;
if((x->type&SMASK) == SRODATA)
shndx = elftextsh + 1;
else
shndx = elftextsh + 2;
break; break;
case 'B': case 'B':
type = STT_OBJECT; type = STT_OBJECT;
shndx = elftextsh + 3;
break; break;
} }
// TODO(minux): we need to place all STB_LOCAL precede all STB_GLOBAL and xo = x;
// STB_WEAK symbols in the symbol table while(xo->outer != nil)
xo = xo->outer;
if(xo->sect == nil) {
cursym = x;
diag("missing section in putelfsym");
return;
}
if(xo->sect->elfsect == nil) {
cursym = x;
diag("missing ELF section in putelfsym");
return;
}
// One pass for each binding: STB_LOCAL, STB_GLOBAL,
// maybe one day STB_WEAK.
bind = (ver || (x->type & SHIDDEN)) ? STB_LOCAL : STB_GLOBAL; bind = (ver || (x->type & SHIDDEN)) ? STB_LOCAL : STB_GLOBAL;
if(bind != elfbind)
return;
off = putelfstr(s); off = putelfstr(s);
putelfsyment(off, addr, size, (bind<<4)|(type&0xf), shndx, (x->type & SHIDDEN) ? 2 : 0); putelfsyment(off, addr, size, (bind<<4)|(type&0xf), xo->sect->elfsect->shnum, (x->type & SHIDDEN) ? 2 : 0);
x->elfsym = numelfsym++;
} }
void void
...@@ -119,6 +135,12 @@ asmelfsym(void) ...@@ -119,6 +135,12 @@ asmelfsym(void)
{ {
// the first symbol entry is reserved // the first symbol entry is reserved
putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0); putelfsyment(0, 0, 0, (STB_LOCAL<<4)|STT_NOTYPE, 0, 0);
elfbind = STB_LOCAL;
genasmsym(putelfsym);
elfbind = STB_GLOBAL;
elfglobalsymndx = numelfsym;
genasmsym(putelfsym); genasmsym(putelfsym);
} }
...@@ -354,8 +376,7 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ) ...@@ -354,8 +376,7 @@ putsymb(Sym *s, char *name, int t, vlong v, vlong size, int ver, Sym *typ)
void void
symtab(void) symtab(void)
{ {
Sym *s; Sym *s, *symtype, *symtypelink, *symgostring;
dosymtype(); dosymtype();
// Define these so that they'll get put into the symbol table. // Define these so that they'll get put into the symbol table.
...@@ -387,11 +408,15 @@ symtab(void) ...@@ -387,11 +408,15 @@ symtab(void)
s->type = STYPE; s->type = STYPE;
s->size = 0; s->size = 0;
s->reachable = 1; s->reachable = 1;
symtype = s;
s = lookup("go.string.*", 0); s = lookup("go.string.*", 0);
s->type = SGOSTRING; s->type = SGOSTRING;
s->size = 0; s->size = 0;
s->reachable = 1; s->reachable = 1;
symgostring = s;
symtypelink = lookup("typelink", 0);
symt = lookup("symtab", 0); symt = lookup("symtab", 0);
symt->type = SSYMTAB; symt->type = SSYMTAB;
...@@ -408,14 +433,17 @@ symtab(void) ...@@ -408,14 +433,17 @@ symtab(void)
if(strncmp(s->name, "type.", 5) == 0) { if(strncmp(s->name, "type.", 5) == 0) {
s->type = STYPE; s->type = STYPE;
s->hide = 1; s->hide = 1;
s->outer = symtype;
} }
if(strncmp(s->name, "go.typelink.", 12) == 0) { if(strncmp(s->name, "go.typelink.", 12) == 0) {
s->type = STYPELINK; s->type = STYPELINK;
s->hide = 1; s->hide = 1;
s->outer = symtypelink;
} }
if(strncmp(s->name, "go.string.", 10) == 0) { if(strncmp(s->name, "go.string.", 10) == 0) {
s->type = SGOSTRING; s->type = SGOSTRING;
s->hide = 1; s->hide = 1;
s->outer = symgostring;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment