if(HEADTYPE == Hnetbsd)
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
addstring(shstrtab, ".rodata");
+ addstring(shstrtab, ".gcdata");
+ addstring(shstrtab, ".gcbss");
addstring(shstrtab, ".gosymtab");
addstring(shstrtab, ".gopclntab");
if(!debug['s']) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
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) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len);
case SNOPTRDATA:
case SSYMTAB:
case SPCLNTAB:
+ case SGCDATA:
+ case SGCBSS:
if(!s->reachable)
continue;
put(s, s->name, 'D', s->value, s->size, s->version, s->gotype);
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata");
+ addstring(shstrtab, ".gcdata");
+ addstring(shstrtab, ".gcbss");
addstring(shstrtab, ".gosymtab");
addstring(shstrtab, ".gopclntab");
if(!debug['s']) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
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) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len);
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);
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata");
+ addstring(shstrtab, ".gcdata");
+ addstring(shstrtab, ".gcbss");
addstring(shstrtab, ".gosymtab");
addstring(shstrtab, ".gopclntab");
if(!debug['s']) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
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) {
cseek(sect->vaddr - segtext.vaddr + segtext.fileoff);
datblk(sect->vaddr, sect->len);
case SNOPTRDATA:
case SSYMTAB:
case SPCLNTAB:
+ case SGCDATA:
+ case SGCBSS:
if(!s->reachable)
continue;
put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
{
if(n->sym != S && n->realtype != T)
if(strncmp(n->sym->name, "autotmp_", 8) != 0)
- if(strncmp(n->sym->name, "statictmp_", 8) != 0)
return typename(n->realtype)->left->sym;
return S;
#include "../ld/lib.h"
#include "../ld/elf.h"
#include "../ld/pe.h"
+#include "../../pkg/runtime/mgc0.h"
void dynreloc(void);
static vlong addaddrplus4(Sym *s, Sym *t, int32 add);
}
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;
uchar *cast;
if(s->type == 0)
s->type = SDATA;
s->reachable = 1;
- r = s->size;
- s->size += wid;
- symgrow(s, s->size);
- assert(r+wid <= s->size);
+ if(s->size < off+wid) {
+ s->size = off+wid;
+ symgrow(s, s->size);
+ }
fl = v;
cast = (uchar*)&fl;
switch(wid) {
case 1:
- s->p[r] = cast[inuxi1[0]];
+ s->p[off] = cast[inuxi1[0]];
break;
case 2:
for(i=0; i<2; i++)
- s->p[r+i] = cast[inuxi2[i]];
+ s->p[off+i] = cast[inuxi2[i]];
break;
case 4:
for(i=0; i<4; i++)
- s->p[r+i] = cast[inuxi4[i]];
+ s->p[off+i] = cast[inuxi4[i]];
break;
case 8:
o = v;
cast = (uchar*)&o;
for(i=0; i<8; i++)
- s->p[r+i] = cast[inuxi8[i]];
+ s->p[off+i] = cast[inuxi8[i]];
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
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
addaddrplus(Sym *s, Sym *t, int32 add)
{
}
}
+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
dodata(void)
{
int32 t, datsize;
- Section *sect, *noptr;
+ Section *sect;
Sym *s, *last, **l;
+ Sym *gcdata1, *gcbss1;
if(debug['v'])
Bprint(&bso, "%5.2f dodata\n", cputime());
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;
datap = nil;
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.
+ * 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 */
sect = addsection(&segtext, ".rodata", 04);
sect->vaddr = 0;
datsize = 0;
s = datap;
- for(; s != nil && s->type < SSYMTAB; s = s->next) {
+ for(; s != nil && s->type < SGCDATA; s = s->next) {
if(s->align != 0)
datsize = rnd(datsize, s->align);
s->type = SRODATA;
}
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 */
sect = addsection(&segtext, ".gosymtab", 04);
sect->vaddr = datsize;
datsize += rnd(s->size, PtrSize);
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
address(void)
{
Section *s, *text, *data, *rodata, *symtab, *pclntab, *noptr, *bss, *noptrbss;
+ Section *gcdata, *gcbss;
Sym *sym, *sub;
uvlong va;
text = segtext.sect;
rodata = text->next;
- symtab = rodata->next;
+ gcdata = rodata->next;
+ gcbss = gcdata->next;
+ symtab = gcbss->next;
pclntab = symtab->next;
for(sym = datap; sym != nil; sym = sym->next) {
xdefine("etext", STEXT, text->vaddr + text->len);
xdefine("rodata", SRODATA, rodata->vaddr);
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("esymtab", SRODATA, symtab->vaddr + symtab->len);
xdefine("pclntab", SRODATA, pclntab->vaddr);
--- /dev/null
+// 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);
+}
#include "../ld/elf.h"
#include "../ld/macho.h"
#include "../ld/pe.h"
+#include "../../pkg/runtime/typekind.h"
/*
* Offsets and sizes of the debug_* sections in the cout file.
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
enum {
SSTRING,
SGOSTRING,
SRODATA,
+ SGCDATA,
+ SGCBSS,
SSYMTAB,
SPCLNTAB,
SELFROSECT,
void symgrow(Sym*, int32);
void addstrdata(char*, char*);
vlong addstring(Sym*, char*);
+vlong adduint8(Sym*, uint8);
+vlong adduint16(Sym*, uint16);
vlong adduint32(Sym*, uint32);
vlong adduint64(Sym*, uint64);
vlong addaddr(Sym*, Sym*);
vlong addaddrplus(Sym*, Sym*, int32);
vlong addpcrelplus(Sym*, Sym*, int32);
vlong addsize(Sym*, Sym*);
-vlong adduint8(Sym*, uint8);
-vlong adduint16(Sym*, uint16);
+void setuint8(Sym*, vlong, uint8);
+void setuint16(Sym*, vlong, uint16);
+void setuint32(Sym*, vlong, uint32);
+void setuint64(Sym*, vlong, uint64);
void asmsym(void);
void asmelfsym(void);
void asmplan9sym(void);
void cwrite(void*, int);
void importcycles(void);
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*);
xdefine("etext", STEXT, 0);
xdefine("rodata", 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("enoptrdata", SNOPTRDATA, 0);
xdefine("data", SDATA, 0);