mirror of
https://github.com/golang/go
synced 2024-11-22 01:44:40 -07:00
ld: add .gcdata and .gcbss sections
R=rsc CC=golang-dev https://golang.org/cl/6281048
This commit is contained in:
parent
9a82324fb7
commit
032e5bfb30
@ -505,6 +505,8 @@ doelf(void)
|
|||||||
if(HEADTYPE == Hnetbsd)
|
if(HEADTYPE == Hnetbsd)
|
||||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||||
addstring(shstrtab, ".rodata");
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gcdata");
|
||||||
|
addstring(shstrtab, ".gcbss");
|
||||||
addstring(shstrtab, ".gosymtab");
|
addstring(shstrtab, ".gosymtab");
|
||||||
addstring(shstrtab, ".gopclntab");
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
@ -661,7 +663,7 @@ asmb(void)
|
|||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
/* output read-only data in text segment (rodata, gosymtab, pclntab, ...) */
|
||||||
for(sect = sect->next; sect != nil; sect = sect->next) {
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
@ -2274,6 +2276,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
|
|||||||
case SNOPTRDATA:
|
case SNOPTRDATA:
|
||||||
case SSYMTAB:
|
case SSYMTAB:
|
||||||
case SPCLNTAB:
|
case SPCLNTAB:
|
||||||
|
case SGCDATA:
|
||||||
|
case SGCBSS:
|
||||||
if(!s->reachable)
|
if(!s->reachable)
|
||||||
continue;
|
continue;
|
||||||
put(s, s->name, 'D', s->value, s->size, s->version, s->gotype);
|
put(s, s->name, 'D', s->value, s->size, s->version, s->gotype);
|
||||||
|
@ -579,6 +579,8 @@ doelf(void)
|
|||||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||||
addstring(shstrtab, ".elfdata");
|
addstring(shstrtab, ".elfdata");
|
||||||
addstring(shstrtab, ".rodata");
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gcdata");
|
||||||
|
addstring(shstrtab, ".gcbss");
|
||||||
addstring(shstrtab, ".gosymtab");
|
addstring(shstrtab, ".gosymtab");
|
||||||
addstring(shstrtab, ".gopclntab");
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
@ -732,7 +734,7 @@ asmb(void)
|
|||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
/* output read-only data in text segment (rodata, gosymtab, pclntab, ...) */
|
||||||
for(sect = sect->next; sect != nil; sect = sect->next) {
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
@ -1200,6 +1202,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
|
|||||||
case SSTRING:
|
case SSTRING:
|
||||||
case SGOSTRING:
|
case SGOSTRING:
|
||||||
case SWINDOWS:
|
case SWINDOWS:
|
||||||
|
case SGCDATA:
|
||||||
|
case SGCBSS:
|
||||||
if(!s->reachable)
|
if(!s->reachable)
|
||||||
continue;
|
continue;
|
||||||
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
||||||
|
@ -536,6 +536,8 @@ doelf(void)
|
|||||||
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
|
||||||
addstring(shstrtab, ".elfdata");
|
addstring(shstrtab, ".elfdata");
|
||||||
addstring(shstrtab, ".rodata");
|
addstring(shstrtab, ".rodata");
|
||||||
|
addstring(shstrtab, ".gcdata");
|
||||||
|
addstring(shstrtab, ".gcbss");
|
||||||
addstring(shstrtab, ".gosymtab");
|
addstring(shstrtab, ".gosymtab");
|
||||||
addstring(shstrtab, ".gopclntab");
|
addstring(shstrtab, ".gopclntab");
|
||||||
if(!debug['s']) {
|
if(!debug['s']) {
|
||||||
@ -684,7 +686,7 @@ asmb(void)
|
|||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
codeblk(sect->vaddr, sect->len);
|
codeblk(sect->vaddr, sect->len);
|
||||||
|
|
||||||
/* output read-only data in text segment (rodata, gosymtab and pclntab) */
|
/* output read-only data in text segment (rodata, gosymtab, pclntab, ...) */
|
||||||
for(sect = sect->next; sect != nil; sect = sect->next) {
|
for(sect = sect->next; sect != nil; sect = sect->next) {
|
||||||
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
|
||||||
datblk(sect->vaddr, sect->len);
|
datblk(sect->vaddr, sect->len);
|
||||||
@ -1266,6 +1268,8 @@ genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*))
|
|||||||
case SNOPTRDATA:
|
case SNOPTRDATA:
|
||||||
case SSYMTAB:
|
case SSYMTAB:
|
||||||
case SPCLNTAB:
|
case SPCLNTAB:
|
||||||
|
case SGCDATA:
|
||||||
|
case SGCBSS:
|
||||||
if(!s->reachable)
|
if(!s->reachable)
|
||||||
continue;
|
continue;
|
||||||
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
|
||||||
|
@ -3515,7 +3515,6 @@ ngotype(Node *n)
|
|||||||
{
|
{
|
||||||
if(n->sym != S && n->realtype != T)
|
if(n->sym != S && n->realtype != T)
|
||||||
if(strncmp(n->sym->name, "autotmp_", 8) != 0)
|
if(strncmp(n->sym->name, "autotmp_", 8) != 0)
|
||||||
if(strncmp(n->sym->name, "statictmp_", 8) != 0)
|
|
||||||
return typename(n->realtype)->left->sym;
|
return typename(n->realtype)->left->sym;
|
||||||
|
|
||||||
return S;
|
return S;
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include "../ld/lib.h"
|
#include "../ld/lib.h"
|
||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
#include "../ld/pe.h"
|
#include "../ld/pe.h"
|
||||||
|
#include "../../pkg/runtime/mgc0.h"
|
||||||
|
|
||||||
void dynreloc(void);
|
void dynreloc(void);
|
||||||
static vlong addaddrplus4(Sym *s, Sym *t, int32 add);
|
static vlong addaddrplus4(Sym *s, Sym *t, int32 add);
|
||||||
@ -628,41 +629,51 @@ addstring(Sym *s, char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
vlong
|
vlong
|
||||||
adduintxx(Sym *s, uint64 v, int wid)
|
setuintxx(Sym *s, vlong off, uint64 v, int wid)
|
||||||
{
|
{
|
||||||
int32 i, r, fl;
|
int32 i, fl;
|
||||||
vlong o;
|
vlong o;
|
||||||
uchar *cast;
|
uchar *cast;
|
||||||
|
|
||||||
if(s->type == 0)
|
if(s->type == 0)
|
||||||
s->type = SDATA;
|
s->type = SDATA;
|
||||||
s->reachable = 1;
|
s->reachable = 1;
|
||||||
r = s->size;
|
if(s->size < off+wid) {
|
||||||
s->size += wid;
|
s->size = off+wid;
|
||||||
symgrow(s, s->size);
|
symgrow(s, s->size);
|
||||||
assert(r+wid <= s->size);
|
}
|
||||||
fl = v;
|
fl = v;
|
||||||
cast = (uchar*)&fl;
|
cast = (uchar*)&fl;
|
||||||
switch(wid) {
|
switch(wid) {
|
||||||
case 1:
|
case 1:
|
||||||
s->p[r] = cast[inuxi1[0]];
|
s->p[off] = cast[inuxi1[0]];
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
for(i=0; i<2; i++)
|
for(i=0; i<2; i++)
|
||||||
s->p[r+i] = cast[inuxi2[i]];
|
s->p[off+i] = cast[inuxi2[i]];
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
for(i=0; i<4; i++)
|
for(i=0; i<4; i++)
|
||||||
s->p[r+i] = cast[inuxi4[i]];
|
s->p[off+i] = cast[inuxi4[i]];
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
o = v;
|
o = v;
|
||||||
cast = (uchar*)&o;
|
cast = (uchar*)&o;
|
||||||
for(i=0; i<8; i++)
|
for(i=0; i<8; i++)
|
||||||
s->p[r+i] = cast[inuxi8[i]];
|
s->p[off+i] = cast[inuxi8[i]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return r;
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
adduintxx(Sym *s, uint64 v, int wid)
|
||||||
|
{
|
||||||
|
int32 off;
|
||||||
|
|
||||||
|
off = s->size;
|
||||||
|
setuintxx(s, off, v, wid);
|
||||||
|
return off;
|
||||||
}
|
}
|
||||||
|
|
||||||
vlong
|
vlong
|
||||||
@ -689,6 +700,30 @@ adduint64(Sym *s, uint64 v)
|
|||||||
return adduintxx(s, v, 8);
|
return adduintxx(s, v, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setuint8(Sym *s, vlong r, uint8 v)
|
||||||
|
{
|
||||||
|
setuintxx(s, r, v, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setuint16(Sym *s, vlong r, uint16 v)
|
||||||
|
{
|
||||||
|
setuintxx(s, r, v, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setuint32(Sym *s, vlong r, uint32 v)
|
||||||
|
{
|
||||||
|
setuintxx(s, r, v, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setuint64(Sym *s, vlong r, uint64 v)
|
||||||
|
{
|
||||||
|
setuintxx(s, r, v, 8);
|
||||||
|
}
|
||||||
|
|
||||||
vlong
|
vlong
|
||||||
addaddrplus(Sym *s, Sym *t, int32 add)
|
addaddrplus(Sym *s, Sym *t, int32 add)
|
||||||
{
|
{
|
||||||
@ -793,17 +828,87 @@ dosymtype(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
alignsymsize(int32 s)
|
||||||
|
{
|
||||||
|
if(s >= PtrSize)
|
||||||
|
s = rnd(s, PtrSize);
|
||||||
|
else if(s > 2)
|
||||||
|
s = rnd(s, 4);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32
|
||||||
|
aligndatsize(int32 datsize, Sym *s)
|
||||||
|
{
|
||||||
|
int32 t;
|
||||||
|
|
||||||
|
if(s->align != 0) {
|
||||||
|
datsize = rnd(datsize, s->align);
|
||||||
|
} else {
|
||||||
|
t = alignsymsize(s->size);
|
||||||
|
if(t & 1) {
|
||||||
|
;
|
||||||
|
} else if(t & 2)
|
||||||
|
datsize = rnd(datsize, 2);
|
||||||
|
else if(t & 4)
|
||||||
|
datsize = rnd(datsize, 4);
|
||||||
|
else
|
||||||
|
datsize = rnd(datsize, 8);
|
||||||
|
}
|
||||||
|
return datsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gcaddsym(Sym *gc, Sym *s, int32 off)
|
||||||
|
{
|
||||||
|
int32 a;
|
||||||
|
Sym *gotype;
|
||||||
|
|
||||||
|
if(s->size < PtrSize)
|
||||||
|
return;
|
||||||
|
if(strcmp(s->name, ".string") == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
gotype = s->gotype;
|
||||||
|
if(gotype != nil) {
|
||||||
|
//print("gcaddsym: %s %d %s\n", s->name, s->size, gotype->name);
|
||||||
|
adduintxx(gc, GC_CALL, PtrSize);
|
||||||
|
adduintxx(gc, off, PtrSize);
|
||||||
|
addaddrplus(gc, decodetype_gc(gotype), 1*PtrSize);
|
||||||
|
} else {
|
||||||
|
//print("gcaddsym: %s %d <unknown type>\n", s->name, s->size);
|
||||||
|
for(a = -off&(PtrSize-1); a+PtrSize<=s->size; a+=PtrSize) {
|
||||||
|
adduintxx(gc, GC_APTR, PtrSize);
|
||||||
|
adduintxx(gc, off+a, PtrSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
dodata(void)
|
dodata(void)
|
||||||
{
|
{
|
||||||
int32 t, datsize;
|
int32 t, datsize;
|
||||||
Section *sect, *noptr;
|
Section *sect;
|
||||||
Sym *s, *last, **l;
|
Sym *s, *last, **l;
|
||||||
|
Sym *gcdata1, *gcbss1;
|
||||||
|
|
||||||
if(debug['v'])
|
if(debug['v'])
|
||||||
Bprint(&bso, "%5.2f dodata\n", cputime());
|
Bprint(&bso, "%5.2f dodata\n", cputime());
|
||||||
Bflush(&bso);
|
Bflush(&bso);
|
||||||
|
|
||||||
|
// define garbage collection symbols
|
||||||
|
gcdata1 = lookup("gcdata1", 0);
|
||||||
|
gcdata1->type = SGCDATA;
|
||||||
|
gcdata1->reachable = 1;
|
||||||
|
gcbss1 = lookup("gcbss1", 0);
|
||||||
|
gcbss1->type = SGCBSS;
|
||||||
|
gcbss1->reachable = 1;
|
||||||
|
|
||||||
|
// size of .data and .bss section. the zero value is later replaced by the actual size of the section.
|
||||||
|
adduintxx(gcdata1, 0, PtrSize);
|
||||||
|
adduintxx(gcbss1, 0, PtrSize);
|
||||||
|
|
||||||
last = nil;
|
last = nil;
|
||||||
datap = nil;
|
datap = nil;
|
||||||
|
|
||||||
@ -847,16 +952,102 @@ dodata(void)
|
|||||||
datap = datsort(datap);
|
datap = datsort(datap);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* allocate data sections. list is sorted by type,
|
* allocate sections. list is sorted by type,
|
||||||
* so we can just walk it for each piece we want to emit.
|
* so we can just walk it for each piece we want to emit.
|
||||||
|
* segdata is processed before segtext, because we need
|
||||||
|
* to see all symbols in the .data and .bss sections in order
|
||||||
|
* to generate garbage collection information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* begin segdata */
|
||||||
|
|
||||||
|
/* skip symbols belonging to segtext */
|
||||||
|
s = datap;
|
||||||
|
for(; s != nil && s->type < SELFSECT; s = s->next);
|
||||||
|
|
||||||
|
/* writable ELF sections */
|
||||||
|
datsize = 0;
|
||||||
|
for(; s != nil && s->type < SNOPTRDATA; s = s->next) {
|
||||||
|
sect = addsection(&segdata, s->name, 06);
|
||||||
|
if(s->align != 0)
|
||||||
|
datsize = rnd(datsize, s->align);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
s->type = SDATA;
|
||||||
|
s->value = datsize;
|
||||||
|
datsize += rnd(s->size, PtrSize);
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pointer-free data */
|
||||||
|
sect = addsection(&segdata, ".noptrdata", 06);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil && s->type < SDATA; s = s->next) {
|
||||||
|
s->type = SDATA;
|
||||||
|
t = alignsymsize(s->size);
|
||||||
|
datsize = aligndatsize(datsize, s);
|
||||||
|
s->value = datsize;
|
||||||
|
datsize += t;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
|
/* data */
|
||||||
|
sect = addsection(&segdata, ".data", 06);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil && s->type < SBSS; s = s->next) {
|
||||||
|
s->type = SDATA;
|
||||||
|
t = alignsymsize(s->size);
|
||||||
|
datsize = aligndatsize(datsize, s);
|
||||||
|
s->value = datsize;
|
||||||
|
gcaddsym(gcdata1, s, datsize - sect->vaddr); // gc
|
||||||
|
datsize += t;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
|
adduintxx(gcdata1, GC_END, PtrSize);
|
||||||
|
setuintxx(gcdata1, 0, sect->len, PtrSize);
|
||||||
|
|
||||||
|
/* bss */
|
||||||
|
sect = addsection(&segdata, ".bss", 06);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil && s->type < SNOPTRBSS; s = s->next) {
|
||||||
|
t = alignsymsize(s->size);
|
||||||
|
datsize = aligndatsize(datsize, s);
|
||||||
|
s->value = datsize;
|
||||||
|
gcaddsym(gcbss1, s, datsize - sect->vaddr); // gc
|
||||||
|
datsize += t;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
|
adduintxx(gcbss1, GC_END, PtrSize);
|
||||||
|
setuintxx(gcbss1, 0, sect->len, PtrSize);
|
||||||
|
|
||||||
|
/* pointer-free bss */
|
||||||
|
sect = addsection(&segdata, ".noptrbss", 06);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil; s = s->next) {
|
||||||
|
if(s->type > SNOPTRBSS) {
|
||||||
|
cursym = s;
|
||||||
|
diag("unexpected symbol type %d", s->type);
|
||||||
|
}
|
||||||
|
t = alignsymsize(s->size);
|
||||||
|
datsize = aligndatsize(datsize, s);
|
||||||
|
s->value = datsize;
|
||||||
|
datsize += t;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
|
/* 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;
|
||||||
datsize = 0;
|
datsize = 0;
|
||||||
s = datap;
|
s = datap;
|
||||||
for(; s != nil && s->type < SSYMTAB; s = s->next) {
|
for(; s != nil && s->type < SGCDATA; s = s->next) {
|
||||||
if(s->align != 0)
|
if(s->align != 0)
|
||||||
datsize = rnd(datsize, s->align);
|
datsize = rnd(datsize, s->align);
|
||||||
s->type = SRODATA;
|
s->type = SRODATA;
|
||||||
@ -865,6 +1056,28 @@ dodata(void)
|
|||||||
}
|
}
|
||||||
sect->len = datsize - sect->vaddr;
|
sect->len = datsize - sect->vaddr;
|
||||||
|
|
||||||
|
/* gcdata */
|
||||||
|
sect = addsection(&segtext, ".gcdata", 04);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil && s->type == SGCDATA; s = s->next) {
|
||||||
|
s->type = SRODATA;
|
||||||
|
s->value = datsize;
|
||||||
|
datsize += s->size;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
|
/* gcbss */
|
||||||
|
sect = addsection(&segtext, ".gcbss", 04);
|
||||||
|
sect->vaddr = datsize;
|
||||||
|
for(; s != nil && s->type == SGCBSS; s = s->next) {
|
||||||
|
s->type = SRODATA;
|
||||||
|
s->value = datsize;
|
||||||
|
datsize += s->size;
|
||||||
|
}
|
||||||
|
sect->len = datsize - sect->vaddr;
|
||||||
|
datsize = rnd(datsize, PtrSize);
|
||||||
|
|
||||||
/* gosymtab */
|
/* gosymtab */
|
||||||
sect = addsection(&segtext, ".gosymtab", 04);
|
sect = addsection(&segtext, ".gosymtab", 04);
|
||||||
sect->vaddr = datsize;
|
sect->vaddr = datsize;
|
||||||
@ -898,96 +1111,6 @@ dodata(void)
|
|||||||
datsize += rnd(s->size, PtrSize);
|
datsize += rnd(s->size, PtrSize);
|
||||||
sect->len = datsize - sect->vaddr;
|
sect->len = datsize - sect->vaddr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writable ELF sections */
|
|
||||||
datsize = 0;
|
|
||||||
for(; s != nil && s->type < SNOPTRDATA; s = s->next) {
|
|
||||||
sect = addsection(&segdata, s->name, 06);
|
|
||||||
if(s->align != 0)
|
|
||||||
datsize = rnd(datsize, s->align);
|
|
||||||
sect->vaddr = datsize;
|
|
||||||
s->type = SDATA;
|
|
||||||
s->value = datsize;
|
|
||||||
datsize += rnd(s->size, PtrSize);
|
|
||||||
sect->len = datsize - sect->vaddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pointer-free data, then data */
|
|
||||||
sect = addsection(&segdata, ".noptrdata", 06);
|
|
||||||
sect->vaddr = datsize;
|
|
||||||
noptr = sect;
|
|
||||||
for(; ; s = s->next) {
|
|
||||||
if((s == nil || s->type >= SDATA) && sect == noptr) {
|
|
||||||
// finish noptrdata, start data
|
|
||||||
datsize = rnd(datsize, 8);
|
|
||||||
sect->len = datsize - sect->vaddr;
|
|
||||||
sect = addsection(&segdata, ".data", 06);
|
|
||||||
sect->vaddr = datsize;
|
|
||||||
}
|
|
||||||
if(s == nil || s->type >= SBSS) {
|
|
||||||
// finish data
|
|
||||||
sect->len = datsize - sect->vaddr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s->type = SDATA;
|
|
||||||
t = s->size;
|
|
||||||
if(t >= PtrSize)
|
|
||||||
t = rnd(t, PtrSize);
|
|
||||||
else if(t > 2)
|
|
||||||
t = rnd(t, 4);
|
|
||||||
if(s->align != 0)
|
|
||||||
datsize = rnd(datsize, s->align);
|
|
||||||
else if(t & 1) {
|
|
||||||
;
|
|
||||||
} else if(t & 2)
|
|
||||||
datsize = rnd(datsize, 2);
|
|
||||||
else if(t & 4)
|
|
||||||
datsize = rnd(datsize, 4);
|
|
||||||
else
|
|
||||||
datsize = rnd(datsize, 8);
|
|
||||||
s->value = datsize;
|
|
||||||
datsize += t;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* bss, then pointer-free bss */
|
|
||||||
noptr = nil;
|
|
||||||
sect = addsection(&segdata, ".bss", 06);
|
|
||||||
sect->vaddr = datsize;
|
|
||||||
for(; ; s = s->next) {
|
|
||||||
if((s == nil || s->type >= SNOPTRBSS) && noptr == nil) {
|
|
||||||
// finish bss, start noptrbss
|
|
||||||
datsize = rnd(datsize, 8);
|
|
||||||
sect->len = datsize - sect->vaddr;
|
|
||||||
sect = addsection(&segdata, ".noptrbss", 06);
|
|
||||||
sect->vaddr = datsize;
|
|
||||||
noptr = sect;
|
|
||||||
}
|
|
||||||
if(s == nil) {
|
|
||||||
sect->len = datsize - sect->vaddr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(s->type > SNOPTRBSS) {
|
|
||||||
cursym = s;
|
|
||||||
diag("unexpected symbol type %d", s->type);
|
|
||||||
}
|
|
||||||
t = s->size;
|
|
||||||
if(t >= PtrSize)
|
|
||||||
t = rnd(t, PtrSize);
|
|
||||||
else if(t > 2)
|
|
||||||
t = rnd(t, 4);
|
|
||||||
if(s->align != 0)
|
|
||||||
datsize = rnd(datsize, s->align);
|
|
||||||
else if(t & 1) {
|
|
||||||
;
|
|
||||||
} else if(t & 2)
|
|
||||||
datsize = rnd(datsize, 2);
|
|
||||||
else if(t & 4)
|
|
||||||
datsize = rnd(datsize, 4);
|
|
||||||
else
|
|
||||||
datsize = rnd(datsize, 8);
|
|
||||||
s->value = datsize;
|
|
||||||
datsize += t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// assign addresses to text
|
// assign addresses to text
|
||||||
@ -1038,6 +1161,7 @@ void
|
|||||||
address(void)
|
address(void)
|
||||||
{
|
{
|
||||||
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
|
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
|
||||||
|
Section *gcdata, *gcbss;
|
||||||
Sym *sym, *sub;
|
Sym *sym, *sub;
|
||||||
uvlong va;
|
uvlong va;
|
||||||
|
|
||||||
@ -1084,7 +1208,9 @@ address(void)
|
|||||||
|
|
||||||
text = segtext.sect;
|
text = segtext.sect;
|
||||||
rodata = text->next;
|
rodata = text->next;
|
||||||
symtab = rodata->next;
|
gcdata = rodata->next;
|
||||||
|
gcbss = gcdata->next;
|
||||||
|
symtab = gcbss->next;
|
||||||
pclntab = symtab->next;
|
pclntab = symtab->next;
|
||||||
|
|
||||||
for(sym = datap; sym != nil; sym = sym->next) {
|
for(sym = datap; sym != nil; sym = sym->next) {
|
||||||
@ -1101,6 +1227,10 @@ address(void)
|
|||||||
xdefine("etext", STEXT, text->vaddr + text->len);
|
xdefine("etext", STEXT, text->vaddr + text->len);
|
||||||
xdefine("rodata", SRODATA, rodata->vaddr);
|
xdefine("rodata", SRODATA, rodata->vaddr);
|
||||||
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
|
xdefine("erodata", SRODATA, rodata->vaddr + rodata->len);
|
||||||
|
xdefine("gcdata", SGCDATA, gcdata->vaddr);
|
||||||
|
xdefine("egcdata", SGCDATA, gcdata->vaddr + gcdata->len);
|
||||||
|
xdefine("gcbss", SGCBSS, gcbss->vaddr);
|
||||||
|
xdefine("egcbss", SGCBSS, gcbss->vaddr + gcbss->len);
|
||||||
xdefine("symtab", SRODATA, symtab->vaddr);
|
xdefine("symtab", SRODATA, symtab->vaddr);
|
||||||
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
|
xdefine("esymtab", SRODATA, symtab->vaddr + symtab->len);
|
||||||
xdefine("pclntab", SRODATA, pclntab->vaddr);
|
xdefine("pclntab", SRODATA, pclntab->vaddr);
|
||||||
|
215
src/cmd/ld/decodesym.c
Normal file
215
src/cmd/ld/decodesym.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#include "l.h"
|
||||||
|
#include "lib.h"
|
||||||
|
#include "../../pkg/runtime/typekind.h"
|
||||||
|
|
||||||
|
// Decoding the type.* symbols. This has to be in sync with
|
||||||
|
// ../../pkg/runtime/type.go, or more specificaly, with what
|
||||||
|
// ../gc/reflect.c stuffs in these.
|
||||||
|
|
||||||
|
static Reloc*
|
||||||
|
decode_reloc(Sym *s, int32 off)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < s->nr; i++)
|
||||||
|
if (s->r[i].off == off)
|
||||||
|
return s->r + i;
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Sym*
|
||||||
|
decode_reloc_sym(Sym *s, int32 off)
|
||||||
|
{
|
||||||
|
Reloc *r;
|
||||||
|
|
||||||
|
r = decode_reloc(s,off);
|
||||||
|
if (r == nil)
|
||||||
|
return nil;
|
||||||
|
return r->sym;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uvlong
|
||||||
|
decode_inuxi(uchar* p, int sz)
|
||||||
|
{
|
||||||
|
uint64 v;
|
||||||
|
uint32 l;
|
||||||
|
uchar *cast, *inuxi;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
v = l = 0;
|
||||||
|
cast = nil;
|
||||||
|
inuxi = nil;
|
||||||
|
switch (sz) {
|
||||||
|
case 2:
|
||||||
|
cast = (uchar*)&l;
|
||||||
|
inuxi = inuxi2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
cast = (uchar*)&l;
|
||||||
|
inuxi = inuxi4;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
cast = (uchar*)&v;
|
||||||
|
inuxi = inuxi8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
diag("dwarf: decode inuxi %d", sz);
|
||||||
|
errorexit();
|
||||||
|
}
|
||||||
|
for (i = 0; i < sz; i++)
|
||||||
|
cast[inuxi[i]] = p[i];
|
||||||
|
if (sz == 8)
|
||||||
|
return v;
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.commonType.kind
|
||||||
|
uint8
|
||||||
|
decodetype_kind(Sym *s)
|
||||||
|
{
|
||||||
|
return s->p[3*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.commonType.size
|
||||||
|
vlong
|
||||||
|
decodetype_size(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + 2*PtrSize, PtrSize); // 0x8 / 0x10
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.commonType.gc
|
||||||
|
Sym*
|
||||||
|
decodetype_gc(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, 3*PtrSize + 8 + 1*PtrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.ArrayType.elem and Type.SliceType.Elem
|
||||||
|
Sym*
|
||||||
|
decodetype_arrayelem(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
decodetype_arraylen(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.PtrType.elem
|
||||||
|
Sym*
|
||||||
|
decodetype_ptrelem(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.MapType.key, elem
|
||||||
|
Sym*
|
||||||
|
decodetype_mapkey(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
||||||
|
}
|
||||||
|
Sym*
|
||||||
|
decodetype_mapvalue(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.ChanType.elem
|
||||||
|
Sym*
|
||||||
|
decodetype_chanelem(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.FuncType.dotdotdot
|
||||||
|
int
|
||||||
|
decodetype_funcdotdotdot(Sym *s)
|
||||||
|
{
|
||||||
|
return s->p[CommonSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.FuncType.in.len
|
||||||
|
int
|
||||||
|
decodetype_funcincount(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize+2*PtrSize, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
decodetype_funcoutcount(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*4, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sym*
|
||||||
|
decodetype_funcintype(Sym *s, int i)
|
||||||
|
{
|
||||||
|
Reloc *r;
|
||||||
|
|
||||||
|
r = decode_reloc(s, CommonSize + PtrSize);
|
||||||
|
if (r == nil)
|
||||||
|
return nil;
|
||||||
|
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sym*
|
||||||
|
decodetype_funcouttype(Sym *s, int i)
|
||||||
|
{
|
||||||
|
Reloc *r;
|
||||||
|
|
||||||
|
r = decode_reloc(s, CommonSize + 2*PtrSize + 2*4);
|
||||||
|
if (r == nil)
|
||||||
|
return nil;
|
||||||
|
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type.StructType.fields.Slice::len
|
||||||
|
int
|
||||||
|
decodetype_structfieldcount(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
StructFieldSize = 5*PtrSize
|
||||||
|
};
|
||||||
|
// Type.StructType.fields[]-> name, typ and offset.
|
||||||
|
char*
|
||||||
|
decodetype_structfieldname(Sym *s, int i)
|
||||||
|
{
|
||||||
|
Reloc *r;
|
||||||
|
|
||||||
|
// go.string."foo" 0x28 / 0x40
|
||||||
|
s = decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize);
|
||||||
|
if (s == nil) // embedded structs have a nil name.
|
||||||
|
return nil;
|
||||||
|
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
|
||||||
|
if (r == nil) // shouldn't happen.
|
||||||
|
return nil;
|
||||||
|
return (char*) r->sym->p + r->add; // the c-string
|
||||||
|
}
|
||||||
|
|
||||||
|
Sym*
|
||||||
|
decodetype_structfieldtype(Sym *s, int i)
|
||||||
|
{
|
||||||
|
return decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize + 2*PtrSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
vlong
|
||||||
|
decodetype_structfieldoffs(Sym *s, int i)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize + PtrSize + 2*4 + i*StructFieldSize + 4*PtrSize, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
// InterfaceTYpe.methods.len
|
||||||
|
vlong
|
||||||
|
decodetype_ifacemethodcount(Sym *s)
|
||||||
|
{
|
||||||
|
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
#include "../ld/elf.h"
|
#include "../ld/elf.h"
|
||||||
#include "../ld/macho.h"
|
#include "../ld/macho.h"
|
||||||
#include "../ld/pe.h"
|
#include "../ld/pe.h"
|
||||||
|
#include "../../pkg/runtime/typekind.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Offsets and sizes of the debug_* sections in the cout file.
|
* Offsets and sizes of the debug_* sections in the cout file.
|
||||||
@ -740,241 +741,6 @@ newabslocexprattr(DWDie *die, vlong addr)
|
|||||||
memmove(die->attr->data, block, i);
|
memmove(die->attr->data, block, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decoding the type.* symbols. This has to be in sync with
|
|
||||||
// ../../pkg/runtime/type.go, or more specificaly, with what
|
|
||||||
// ../gc/reflect.c stuffs in these.
|
|
||||||
|
|
||||||
enum {
|
|
||||||
KindBool = 1,
|
|
||||||
KindInt,
|
|
||||||
KindInt8,
|
|
||||||
KindInt16,
|
|
||||||
KindInt32,
|
|
||||||
KindInt64,
|
|
||||||
KindUint,
|
|
||||||
KindUint8,
|
|
||||||
KindUint16,
|
|
||||||
KindUint32,
|
|
||||||
KindUint64,
|
|
||||||
KindUintptr,
|
|
||||||
KindFloat32,
|
|
||||||
KindFloat64,
|
|
||||||
KindComplex64,
|
|
||||||
KindComplex128,
|
|
||||||
KindArray,
|
|
||||||
KindChan,
|
|
||||||
KindFunc,
|
|
||||||
KindInterface,
|
|
||||||
KindMap,
|
|
||||||
KindPtr,
|
|
||||||
KindSlice,
|
|
||||||
KindString,
|
|
||||||
KindStruct,
|
|
||||||
KindUnsafePointer,
|
|
||||||
|
|
||||||
KindNoPointers = 1<<7,
|
|
||||||
|
|
||||||
// size of Type interface header + CommonType structure.
|
|
||||||
CommonSize = 2*PtrSize+ 6*PtrSize + 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
static Reloc*
|
|
||||||
decode_reloc(Sym *s, int32 off)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < s->nr; i++)
|
|
||||||
if (s->r[i].off == off)
|
|
||||||
return s->r + i;
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sym*
|
|
||||||
decode_reloc_sym(Sym *s, int32 off)
|
|
||||||
{
|
|
||||||
Reloc *r;
|
|
||||||
|
|
||||||
r = decode_reloc(s,off);
|
|
||||||
if (r == nil)
|
|
||||||
return nil;
|
|
||||||
return r->sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uvlong
|
|
||||||
decode_inuxi(uchar* p, int sz)
|
|
||||||
{
|
|
||||||
uint64 v;
|
|
||||||
uint32 l;
|
|
||||||
uchar *cast, *inuxi;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
v = l = 0;
|
|
||||||
cast = nil;
|
|
||||||
inuxi = nil;
|
|
||||||
switch (sz) {
|
|
||||||
case 2:
|
|
||||||
cast = (uchar*)&l;
|
|
||||||
inuxi = inuxi2;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
cast = (uchar*)&l;
|
|
||||||
inuxi = inuxi4;
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
cast = (uchar*)&v;
|
|
||||||
inuxi = inuxi8;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
diag("dwarf: decode inuxi %d", sz);
|
|
||||||
errorexit();
|
|
||||||
}
|
|
||||||
for (i = 0; i < sz; i++)
|
|
||||||
cast[inuxi[i]] = p[i];
|
|
||||||
if (sz == 8)
|
|
||||||
return v;
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.commonType.kind
|
|
||||||
static uint8
|
|
||||||
decodetype_kind(Sym *s)
|
|
||||||
{
|
|
||||||
return s->p[3*PtrSize + 7] & ~KindNoPointers; // 0x13 / 0x1f
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.commonType.size
|
|
||||||
static vlong
|
|
||||||
decodetype_size(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + 2*PtrSize, PtrSize); // 0x8 / 0x10
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.ArrayType.elem and Type.SliceType.Elem
|
|
||||||
static Sym*
|
|
||||||
decodetype_arrayelem(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
||||||
}
|
|
||||||
|
|
||||||
static vlong
|
|
||||||
decodetype_arraylen(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize+PtrSize, PtrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.PtrType.elem
|
|
||||||
static Sym*
|
|
||||||
decodetype_ptrelem(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.MapType.key, elem
|
|
||||||
static Sym*
|
|
||||||
decodetype_mapkey(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
||||||
}
|
|
||||||
static Sym*
|
|
||||||
decodetype_mapvalue(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize+PtrSize); // 0x20 / 0x38
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.ChanType.elem
|
|
||||||
static Sym*
|
|
||||||
decodetype_chanelem(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize); // 0x1c / 0x30
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.FuncType.dotdotdot
|
|
||||||
static int
|
|
||||||
decodetype_funcdotdotdot(Sym *s)
|
|
||||||
{
|
|
||||||
return s->p[CommonSize];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.FuncType.in.len
|
|
||||||
static int
|
|
||||||
decodetype_funcincount(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize+2*PtrSize, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
decodetype_funcoutcount(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize+3*PtrSize + 2*4, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sym*
|
|
||||||
decodetype_funcintype(Sym *s, int i)
|
|
||||||
{
|
|
||||||
Reloc *r;
|
|
||||||
|
|
||||||
r = decode_reloc(s, CommonSize + PtrSize);
|
|
||||||
if (r == nil)
|
|
||||||
return nil;
|
|
||||||
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sym*
|
|
||||||
decodetype_funcouttype(Sym *s, int i)
|
|
||||||
{
|
|
||||||
Reloc *r;
|
|
||||||
|
|
||||||
r = decode_reloc(s, CommonSize + 2*PtrSize + 2*4);
|
|
||||||
if (r == nil)
|
|
||||||
return nil;
|
|
||||||
return decode_reloc_sym(r->sym, r->add + i * PtrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type.StructType.fields.Slice::len
|
|
||||||
static int
|
|
||||||
decodetype_structfieldcount(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
StructFieldSize = 5*PtrSize
|
|
||||||
};
|
|
||||||
// Type.StructType.fields[]-> name, typ and offset.
|
|
||||||
static char*
|
|
||||||
decodetype_structfieldname(Sym *s, int i)
|
|
||||||
{
|
|
||||||
Reloc *r;
|
|
||||||
|
|
||||||
// go.string."foo" 0x28 / 0x40
|
|
||||||
s = decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize);
|
|
||||||
if (s == nil) // embedded structs have a nil name.
|
|
||||||
return nil;
|
|
||||||
r = decode_reloc(s, 0); // s has a pointer to the string data at offset 0
|
|
||||||
if (r == nil) // shouldn't happen.
|
|
||||||
return nil;
|
|
||||||
return (char*) r->sym->p + r->add; // the c-string
|
|
||||||
}
|
|
||||||
|
|
||||||
static Sym*
|
|
||||||
decodetype_structfieldtype(Sym *s, int i)
|
|
||||||
{
|
|
||||||
return decode_reloc_sym(s, CommonSize + PtrSize + 2*4 + i*StructFieldSize + 2*PtrSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
static vlong
|
|
||||||
decodetype_structfieldoffs(Sym *s, int i)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize + PtrSize + 2*4 + i*StructFieldSize + 4*PtrSize, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// InterfaceTYpe.methods.len
|
|
||||||
static vlong
|
|
||||||
decodetype_ifacemethodcount(Sym *s)
|
|
||||||
{
|
|
||||||
return decode_inuxi(s->p + CommonSize + PtrSize, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fake attributes for slices, maps and channel
|
// Fake attributes for slices, maps and channel
|
||||||
enum {
|
enum {
|
||||||
|
@ -39,6 +39,8 @@ enum
|
|||||||
SSTRING,
|
SSTRING,
|
||||||
SGOSTRING,
|
SGOSTRING,
|
||||||
SRODATA,
|
SRODATA,
|
||||||
|
SGCDATA,
|
||||||
|
SGCBSS,
|
||||||
SSYMTAB,
|
SSYMTAB,
|
||||||
SPCLNTAB,
|
SPCLNTAB,
|
||||||
SELFROSECT,
|
SELFROSECT,
|
||||||
@ -186,14 +188,18 @@ void savedata(Sym*, Prog*, char*);
|
|||||||
void symgrow(Sym*, int32);
|
void symgrow(Sym*, int32);
|
||||||
void addstrdata(char*, char*);
|
void addstrdata(char*, char*);
|
||||||
vlong addstring(Sym*, char*);
|
vlong addstring(Sym*, char*);
|
||||||
|
vlong adduint8(Sym*, uint8);
|
||||||
|
vlong adduint16(Sym*, uint16);
|
||||||
vlong adduint32(Sym*, uint32);
|
vlong adduint32(Sym*, uint32);
|
||||||
vlong adduint64(Sym*, uint64);
|
vlong adduint64(Sym*, uint64);
|
||||||
vlong addaddr(Sym*, Sym*);
|
vlong addaddr(Sym*, Sym*);
|
||||||
vlong addaddrplus(Sym*, Sym*, int32);
|
vlong addaddrplus(Sym*, Sym*, int32);
|
||||||
vlong addpcrelplus(Sym*, Sym*, int32);
|
vlong addpcrelplus(Sym*, Sym*, int32);
|
||||||
vlong addsize(Sym*, Sym*);
|
vlong addsize(Sym*, Sym*);
|
||||||
vlong adduint8(Sym*, uint8);
|
void setuint8(Sym*, vlong, uint8);
|
||||||
vlong adduint16(Sym*, uint16);
|
void setuint16(Sym*, vlong, uint16);
|
||||||
|
void setuint32(Sym*, vlong, uint32);
|
||||||
|
void setuint64(Sym*, vlong, uint64);
|
||||||
void asmsym(void);
|
void asmsym(void);
|
||||||
void asmelfsym(void);
|
void asmelfsym(void);
|
||||||
void asmplan9sym(void);
|
void asmplan9sym(void);
|
||||||
@ -315,3 +321,23 @@ void cseek(vlong);
|
|||||||
void cwrite(void*, int);
|
void cwrite(void*, int);
|
||||||
void importcycles(void);
|
void importcycles(void);
|
||||||
int Zconv(Fmt*);
|
int Zconv(Fmt*);
|
||||||
|
|
||||||
|
uint8 decodetype_kind(Sym*);
|
||||||
|
vlong decodetype_size(Sym*);
|
||||||
|
Sym* decodetype_gc(Sym*);
|
||||||
|
Sym* decodetype_arrayelem(Sym*);
|
||||||
|
vlong decodetype_arraylen(Sym*);
|
||||||
|
Sym* decodetype_ptrelem(Sym*);
|
||||||
|
Sym* decodetype_mapkey(Sym*);
|
||||||
|
Sym* decodetype_mapvalue(Sym*);
|
||||||
|
Sym* decodetype_chanelem(Sym*);
|
||||||
|
int decodetype_funcdotdotdot(Sym*);
|
||||||
|
int decodetype_funcincount(Sym*);
|
||||||
|
int decodetype_funcoutcount(Sym*);
|
||||||
|
Sym* decodetype_funcintype(Sym*, int);
|
||||||
|
Sym* decodetype_funcouttype(Sym*, int);
|
||||||
|
int decodetype_structfieldcount(Sym*);
|
||||||
|
char* decodetype_structfieldname(Sym*, int);
|
||||||
|
Sym* decodetype_structfieldtype(Sym*, int);
|
||||||
|
vlong decodetype_structfieldoffs(Sym*, int);
|
||||||
|
vlong decodetype_ifacemethodcount(Sym*);
|
||||||
|
@ -339,6 +339,10 @@ symtab(void)
|
|||||||
xdefine("etext", STEXT, 0);
|
xdefine("etext", STEXT, 0);
|
||||||
xdefine("rodata", SRODATA, 0);
|
xdefine("rodata", SRODATA, 0);
|
||||||
xdefine("erodata", SRODATA, 0);
|
xdefine("erodata", SRODATA, 0);
|
||||||
|
xdefine("gcdata", SGCDATA, 0);
|
||||||
|
xdefine("egcdata", SGCDATA, 0);
|
||||||
|
xdefine("gcbss", SGCBSS, 0);
|
||||||
|
xdefine("egcbss", SGCBSS, 0);
|
||||||
xdefine("noptrdata", SNOPTRDATA, 0);
|
xdefine("noptrdata", SNOPTRDATA, 0);
|
||||||
xdefine("enoptrdata", SNOPTRDATA, 0);
|
xdefine("enoptrdata", SNOPTRDATA, 0);
|
||||||
xdefine("data", SDATA, 0);
|
xdefine("data", SDATA, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user