static int gflag;
static Prog *savepc;
-static void
+void
data(void)
{
gflag = debug['g'];
pc = estrdat;
}
-static void
+void
text(void)
{
if(!savepc)
pc = estrdat;
}
+int
+dsname(Sym *sym, int off, char *t, int n)
+{
+ Prog *p;
+
+ p = gins(ADATA, N, N);
+ p->from.type = D_OREG;
+ p->from.name = D_EXTERN;
+ p->from.etype = TINT32;
+ p->from.offset = off;
+ p->from.reg = NREG;
+ p->from.sym = sym;
+
+ p->reg = n;
+
+ p->to.type = D_SCONST;
+ p->to.name = D_NONE;
+ p->to.reg = NREG;
+ p->to.offset = 0;
+ memmove(p->to.sval, t, n);
+ return off + n;
+}
+
/*
* make a refer to the data s, s+len
* emitting DATA if needed.
void
datastring(char *s, int len, Addr *a)
{
- int w;
- Prog *p;
- Addr ac, ao;
- static int gen;
- struct {
- Strlit lit;
- char buf[100];
- } tmp;
-
- // string
- memset(&ao, 0, sizeof(ao));
- ao.type = D_OREG;
- ao.name = D_STATIC;
- ao.etype = TINT32;
- ao.offset = 0; // fill in
- ao.reg = NREG;
-
- // constant
- memset(&ac, 0, sizeof(ac));
- ac.type = D_CONST;
- ac.name = D_NONE;
- ac.offset = 0; // fill in
- ac.reg = NREG;
-
- // huge strings are made static to avoid long names.
- if(len > 100) {
- snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
- ao.sym = lookup(namebuf);
- ao.name = D_STATIC;
- } else {
- if(len > 0 && s[len-1] == '\0')
- len--;
- tmp.lit.len = len;
- memmove(tmp.lit.s, s, len);
- tmp.lit.s[len] = '\0';
- len++;
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
- ao.sym = pkglookup(namebuf, stringpkg);
- ao.name = D_EXTERN;
- }
- *a = ao;
-
- // only generate data the first time.
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- for(w=0; w<len; w+=8) {
- p = pc;
- gins(ADATA, N, N);
-
- // DATA s+w, [NSNAME], $"xxx"
- p->from = ao;
- p->from.offset = w;
-
- p->reg = NSNAME;
- if(w+8 > len)
- p->reg = len-w;
-
- p->to = ac;
- p->to.type = D_SCONST;
- p->to.offset = len;
- memmove(p->to.sval, s+w, p->reg);
- }
- p = pc;
- ggloblsym(ao.sym, len, ao.name == D_EXTERN);
- if(ao.name == D_STATIC)
- p->from.name = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(s, len);
+ a->type = D_OREG;
+ a->name = D_EXTERN;
+ a->etype = TINT32;
+ a->offset = widthptr+4; // skip header
+ a->reg = NREG;
+ a->sym = sym;
}
/*
void
datagostring(Strlit *sval, Addr *a)
{
- Prog *p;
- Addr ac, ao, ap;
- int32 wi, wp;
- static int gen;
-
- memset(&ac, 0, sizeof(ac));
- memset(&ao, 0, sizeof(ao));
- memset(&ap, 0, sizeof(ap));
-
- // constant
- ac.type = D_CONST;
- ac.name = D_NONE;
- ac.offset = 0; // fill in
- ac.reg = NREG;
-
- // string len+ptr
- ao.type = D_OREG;
- ao.name = D_STATIC; // fill in
- ao.etype = TINT32;
- ao.sym = nil; // fill in
- ao.reg = NREG;
-
- // $string len+ptr
- datastring(sval->s, sval->len, &ap);
- ap.type = D_CONST;
- ap.etype = TINT32;
-
- wi = types[TUINT32]->width;
- wp = types[tptr]->width;
-
- if(ap.name == D_STATIC) {
- // huge strings are made static to avoid long names
- snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
- ao.sym = lookup(namebuf);
- ao.name = D_STATIC;
- } else {
- // small strings get named by their contents,
- // so that multiple modules using the same string
- // can share it.
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
- ao.sym = pkglookup(namebuf, gostringpkg);
- ao.name = D_EXTERN;
- }
-
- *a = ao;
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- // DATA gostring, wp, $cstring
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->reg = wp;
- p->to = ap;
-
- // DATA gostring+wp, wi, $len
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.offset = wp;
- p->reg = wi;
- p->to = ac;
- p->to.offset = sval->len;
-
- p = pc;
- ggloblsym(ao.sym, types[TSTRING]->width, ao.name == D_EXTERN);
- if(ao.name == D_STATIC)
- p->from.name = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(sval->s, sval->len);
+ a->type = D_OREG;
+ a->name = D_EXTERN;
+ a->etype = TINT32;
+ a->offset = 0; // header
+ a->reg = NREG;
+ a->sym = sym;
}
void
uchar foreign; // called by arm if thumb, by thumb if arm
uchar fnptr; // used as fn ptr
Sym* hash; // in hash table
+ Sym* allsym; // in all symbol list
Sym* next; // in text or data list
Sym* sub; // in SSUB list
Sym* outer; // container of sub
LEAF = 1<<2,
STRINGSZ = 200,
- NHASH = 10007,
MINSIZ = 64,
NENT = 100,
MAXIO = 8192,
static int gflag;
static Prog *savepc;
-static void
+void
data(void)
{
gflag = debug['g'];
pc = estrdat;
}
-static void
+void
text(void)
{
if(!savepc)
pc = estrdat;
}
+int
+dsname(Sym *s, int off, char *t, int n)
+{
+ Prog *p;
+
+ p = gins(ADATA, N, N);
+ p->from.type = D_EXTERN;
+ p->from.index = D_NONE;
+ p->from.offset = off;
+ p->from.scale = n;
+ p->from.sym = s;
+
+ p->to.type = D_SCONST;
+ p->to.index = D_NONE;
+ memmove(p->to.sval, t, n);
+ return off + n;
+}
+
/*
* make a refer to the data s, s+len
* emitting DATA if needed.
void
datastring(char *s, int len, Addr *a)
{
- int w;
- Prog *p;
- Addr ac, ao;
- static int gen;
- struct {
- Strlit lit;
- char buf[100];
- } tmp;
-
- // string
- memset(&ao, 0, sizeof(ao));
- ao.type = D_STATIC;
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.offset = 0; // fill in
-
- // constant
- memset(&ac, 0, sizeof(ac));
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // huge strings are made static to avoid long names.
- if(len > 100) {
- snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- if(len > 0 && s[len-1] == '\0')
- len--;
- tmp.lit.len = len;
- memmove(tmp.lit.s, s, len);
- tmp.lit.s[len] = '\0';
- len++;
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
- ao.sym = pkglookup(namebuf, stringpkg);
- ao.type = D_EXTERN;
- }
- *a = ao;
-
- // only generate data the first time.
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- for(w=0; w<len; w+=8) {
- p = pc;
- gins(ADATA, N, N);
-
- // DATA s+w, [NSNAME], $"xxx"
- p->from = ao;
- p->from.offset = w;
-
- p->from.scale = NSNAME;
- if(w+8 > len)
- p->from.scale = len-w;
-
- p->to = ac;
- p->to.type = D_SCONST;
- p->to.offset = len;
- memmove(p->to.sval, s+w, p->from.scale);
- }
- p = pc;
- ggloblsym(ao.sym, len, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(s, len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = widthptr+4; // skip header
+ a->etype = TINT32;
}
/*
void
datagostring(Strlit *sval, Addr *a)
{
- Prog *p;
- Addr ac, ao, ap;
- int32 wi, wp;
- static int gen;
-
- memset(&ac, 0, sizeof(ac));
- memset(&ao, 0, sizeof(ao));
- memset(&ap, 0, sizeof(ap));
-
- // constant
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // string len+ptr
- ao.type = D_STATIC; // fill in
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.sym = nil; // fill in
-
- // $string len+ptr
- datastring(sval->s, sval->len, &ap);
- ap.index = ap.type;
- ap.type = D_ADDR;
- ap.etype = TINT32;
-
- wi = types[TUINT32]->width;
- wp = types[tptr]->width;
-
- if(ap.index == D_STATIC) {
- // huge strings are made static to avoid long names
- snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- // small strings get named by their contents,
- // so that multiple modules using the same string
- // can share it.
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
- ao.sym = pkglookup(namebuf, gostringpkg);
- ao.type = D_EXTERN;
- }
-
- *a = ao;
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- // DATA gostring, wp, $cstring
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.scale = wp;
- p->to = ap;
-
- // DATA gostring+wp, wi, $len
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.offset = wp;
- p->from.scale = wi;
- p->to = ac;
- p->to.offset = sval->len;
-
- p = pc;
- ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(sval->s, sval->len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = 0; // header
+ a->etype = TINT32;
}
void
{
Auto *a;
Sym *s;
- int h;
- for(h=0; h<NHASH; h++) {
- for(s=hash[h]; s!=S; s=s->hash) {
- if(s->hide)
- continue;
- switch(s->type&~SSUB) {
- case SCONST:
- case SRODATA:
- case SDATA:
- case SELFDATA:
- case SMACHOGOT:
- case STYPE:
- case SSTRING:
- case SGOSTRING:
- case SWINDOWS:
- if(!s->reachable)
- continue;
- put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
+ for(s=allsym; s!=S; s=s->allsym) {
+ if(s->hide)
+ continue;
+ switch(s->type&~SSUB) {
+ case SCONST:
+ case SRODATA:
+ case SDATA:
+ case SELFDATA:
+ case SMACHOGOT:
+ case STYPE:
+ case SSTRING:
+ case SGOSTRING:
+ case SWINDOWS:
+ if(!s->reachable)
continue;
+ put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
+ continue;
- case SBSS:
- if(!s->reachable)
- continue;
- put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
+ case SBSS:
+ if(!s->reachable)
continue;
+ 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;
- }
+ case SFILE:
+ put(nil, s->name, 'f', s->value, 0, s->version, 0);
+ continue;
}
}
int32 plt;
int32 got;
Sym* hash; // in hash table
+ Sym* allsym; // in all symbol list
Sym* next; // in text or data list
Sym* sub; // in SSUB list
Sym* outer; // container of sub
enum
{
- NHASH = 10007,
MINSIZ = 8,
STRINGSZ = 200,
MINLC = 1,
{
int o;
- o = Bgetc(f);
+ o = BGETC(f);
if(o < 0 || o >= NSYM || h[o] == nil)
mangle(pn);
return h[o];
Sym *s;
Auto *u;
- t = Bgetc(f);
+ t = BGETC(f);
a->index = D_NONE;
a->scale = 0;
if(t & T_INDEX) {
- a->index = Bgetc(f);
- a->scale = Bgetc(f);
+ a->index = BGETC(f);
+ a->scale = BGETC(f);
}
a->offset = 0;
if(t & T_OFFSET) {
a->type = D_SCONST;
}
if(t & T_TYPE)
- a->type = Bgetc(f);
+ a->type = BGETC(f);
if(a->type < 0 || a->type >= D_SIZE)
mangle(pn);
adrgotype = S;
loop:
if(f->state == Bracteof || Boffset(f) >= eof)
goto eof;
- o = Bgetc(f);
+ o = BGETC(f);
if(o == Beof)
goto eof;
- o |= Bgetc(f) << 8;
+ o |= BGETC(f) << 8;
if(o <= AXXX || o >= ALAST) {
if(o < 0)
goto eof;
sig = 0;
if(o == ASIGNAME)
sig = Bget4(f);
- v = Bgetc(f); /* type */
- o = Bgetc(f); /* sym */
+ v = BGETC(f); /* type */
+ o = BGETC(f); /* sym */
r = 0;
if(v == D_STATIC)
r = version;
pc = estrdat;
}
+int
+dsname(Sym *s, int off, char *t, int n)
+{
+ Prog *p;
+
+ p = gins(ADATA, N, N);
+ p->from.type = D_EXTERN;
+ p->from.index = D_NONE;
+ p->from.offset = off;
+ p->from.scale = n;
+ p->from.sym = s;
+
+ p->to.type = D_SCONST;
+ p->to.index = D_NONE;
+ memmove(p->to.sval, t, n);
+ return off + n;
+}
+
/*
* make a refer to the data s, s+len
* emitting DATA if needed.
void
datastring(char *s, int len, Addr *a)
{
- int w;
- Prog *p;
- Addr ac, ao;
- static int gen;
- struct {
- Strlit lit;
- char buf[100];
- } tmp;
-
- // string
- memset(&ao, 0, sizeof(ao));
- ao.type = D_STATIC;
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.offset = 0; // fill in
-
- // constant
- memset(&ac, 0, sizeof(ac));
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // huge strings are made static to avoid long names.
- if(len > 100) {
- snprint(namebuf, sizeof(namebuf), ".string.%d", gen++);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- if(len > 0 && s[len-1] == '\0')
- len--;
- tmp.lit.len = len;
- memmove(tmp.lit.s, s, len);
- tmp.lit.s[len] = '\0';
- len++;
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
- ao.sym = pkglookup(namebuf, stringpkg);
- ao.type = D_EXTERN;
- }
- *a = ao;
-
- // only generate data the first time.
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- for(w=0; w<len; w+=8) {
- p = pc;
- gins(ADATA, N, N);
-
- // DATA s+w, [NSNAME], $"xxx"
- p->from = ao;
- p->from.offset = w;
-
- p->from.scale = NSNAME;
- if(w+8 > len)
- p->from.scale = len-w;
-
- p->to = ac;
- p->to.type = D_SCONST;
- p->to.offset = len;
- memmove(p->to.sval, s+w, p->from.scale);
- }
- p = pc;
- ggloblsym(ao.sym, len, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(s, len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = widthptr+4; // skip header
+ a->etype = TINT32;
}
/*
void
datagostring(Strlit *sval, Addr *a)
{
- Prog *p;
- Addr ac, ao, ap;
- int32 wi, wp;
- static int gen;
-
- memset(&ac, 0, sizeof(ac));
- memset(&ao, 0, sizeof(ao));
- memset(&ap, 0, sizeof(ap));
-
- // constant
- ac.type = D_CONST;
- ac.index = D_NONE;
- ac.offset = 0; // fill in
-
- // string len+ptr
- ao.type = D_STATIC; // fill in
- ao.index = D_NONE;
- ao.etype = TINT32;
- ao.sym = nil; // fill in
-
- // $string len+ptr
- datastring(sval->s, sval->len, &ap);
- ap.index = ap.type;
- ap.type = D_ADDR;
- ap.etype = TINT32;
-
- wi = types[TUINT32]->width;
- wp = types[tptr]->width;
-
- if(ap.index == D_STATIC) {
- // huge strings are made static to avoid long names
- snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
- ao.sym = lookup(namebuf);
- ao.type = D_STATIC;
- } else {
- // small strings get named by their contents,
- // so that multiple modules using the same string
- // can share it.
- snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
- ao.sym = pkglookup(namebuf, gostringpkg);
- ao.type = D_EXTERN;
- }
-
- *a = ao;
- if(ao.sym->flags & SymUniq)
- return;
- ao.sym->flags |= SymUniq;
-
- data();
- // DATA gostring, wp, $cstring
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.scale = wp;
- p->to = ap;
-
- // DATA gostring+wp, wi, $len
- p = pc;
- gins(ADATA, N, N);
- p->from = ao;
- p->from.offset = wp;
- p->from.scale = wi;
- p->to = ac;
- p->to.offset = sval->len;
-
- p = pc;
- ggloblsym(ao.sym, types[TSTRING]->width, ao.type == D_EXTERN);
- if(ao.type == D_STATIC)
- p->from.type = D_STATIC;
- text();
+ Sym *sym;
+
+ sym = stringsym(sval->s, sval->len);
+ a->type = D_EXTERN;
+ a->sym = sym;
+ a->offset = 0; // header
+ a->etype = TINT32;
}
void
int32 plt;
int32 got;
Sym* hash; // in hash table
+ Sym* allsym; // in all symbol list
Sym* next; // in text or data list
Sym* sub; // in sub list
Sym* outer; // container of sub
enum
{
- NHASH = 10007,
MINSIZ = 4,
STRINGSZ = 200,
MINLC = 1,
int duint64(Sym *s, int off, uint64 v);
int duint8(Sym *s, int off, uint8 v);
int duintptr(Sym *s, int off, uint64 v);
+int dsname(Sym *s, int off, char *dat, int ndat);
void dumpobj(void);
void ieeedtod(uint64 *ieee, double native);
+Sym* stringsym(char*, int);
/*
* print.c
void zfile(Biobuf *b, char *p, int n);
void zhist(Biobuf *b, int line, vlong offset);
void zname(Biobuf *b, Sym *s, int t);
+void data(void);
+void text(void);
runtimepkg = mkpkg(strlit("runtime"));
runtimepkg->name = "runtime";
- stringpkg = mkpkg(strlit("string"));
- stringpkg->name = "string";
-
typepkg = mkpkg(strlit("type"));
typepkg->name = "type";
{
return duintxx(s, off, v, widthptr);
}
+
+Sym*
+stringsym(char *s, int len)
+{
+ static int gen;
+ Sym *sym;
+ int off, n, m;
+ struct {
+ Strlit lit;
+ char buf[110];
+ } tmp;
+ Pkg *pkg;
+
+ if(len > 100) {
+ // huge strings are made static to avoid long names
+ snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
+ pkg = localpkg;
+ } else {
+ // small strings get named by their contents,
+ // so that multiple modules using the same string
+ // can share it.
+ tmp.lit.len = len;
+ memmove(tmp.lit.s, s, len);
+ tmp.lit.s[len] = '\0';
+ snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp);
+ pkg = gostringpkg;
+ }
+ sym = pkglookup(namebuf, pkg);
+
+ // SymUniq flag indicates that data is generated already
+ if(sym->flags & SymUniq)
+ return sym;
+ sym->flags |= SymUniq;
+
+ data();
+ off = 0;
+
+ // string header
+ off = dsymptr(sym, off, sym, widthptr+4);
+ off = duint32(sym, off, len);
+
+ // string data
+ for(n=0; n<len; n+=m) {
+ m = 8;
+ if(m > len-n)
+ m = len-n;
+ off = dsname(sym, off, s+n, m);
+ }
+ off = duint8(sym, off, 0); // terminating NUL for runtime
+ ggloblsym(sym, off, 1);
+ text();
+
+ return sym;
+}
* uncommonType
* ../../pkg/runtime/type.go:/uncommonType
*/
-static Sym*
-dextratype(Type *t)
+static int
+dextratype(Sym *sym, int off, Type *t, int ptroff)
{
int ot, n;
- char *p;
Sym *s;
Sig *a, *m;
m = methods(t);
if(t->sym == nil && m == nil)
- return nil;
+ return off;
+
+ // fill in *extraType pointer in header
+ dsymptr(sym, ptroff, sym, off);
n = 0;
for(a=m; a; a=a->link) {
n++;
}
- p = smprint("_.%#T", t);
- s = pkglookup(p, typepkg);
- ot = 0;
+ ot = off;
+ s = sym;
if(t->sym) {
ot = dgostringptr(s, ot, t->sym->name);
if(t != types[t->etype])
else
ot = duintptr(s, ot, 0);
}
- ggloblsym(s, ot, 0);
- return s;
+ return ot;
}
enum {
dcommontype(Sym *s, int ot, Type *t)
{
int i;
- Sym *s1;
Sym *sptr;
char *p;
else
sptr = weaktypesym(ptrto(t));
- s1 = dextratype(t);
-
// empty interface pointing at this type.
// all the references that we emit are *interface{};
// they point here.
longsymnames = 0;
ot = dgostringptr(s, ot, p); // string
free(p);
- if(s1)
- ot = dsymptr(s, ot, s1, 0); // extraType
- else
- ot = duintptr(s, ot, 0);
- ot = dsymptr(s, ot, sptr, 0); // ptr to type
+
+ // skip pointer to extraType,
+ // which follows the rest of this type structure.
+ // caller will fill in if needed.
+ // otherwise linker will assume 0.
+ ot += widthptr;
+
+ ot = dsymptr(s, ot, sptr, 0); // ptrto type
return ot;
}
static Sym*
dtypesym(Type *t)
{
- int ot, n, isddd, dupok;
+ int ot, xt, n, isddd, dupok;
Sym *s, *s1, *s2;
Sig *a, *m;
Type *t1, *tbase;
ok:
ot = 0;
+ xt = 0;
switch(t->etype) {
default:
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
break;
case TARRAY:
// ../../pkg/runtime/type.go:/ArrayType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s1, 0);
if(t->bound < 0)
ot = duintptr(s, ot, -1);
// ../../pkg/runtime/type.go:/ChanType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s1, 0);
ot = duintptr(s, ot, t->chan);
break;
dtypesym(t1->type);
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = duint8(s, ot, isddd);
// two slice headers: in and out.
// ../../pkg/runtime/type.go:/InterfaceType
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s, ot+widthptr+2*4);
ot = duint32(s, ot, n);
ot = duint32(s, ot, n);
s1 = dtypesym(t->down);
s2 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s1, 0);
ot = dsymptr(s, ot, s2, 0);
break;
// ../../pkg/runtime/type.go:/PtrType
s1 = dtypesym(t->type);
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s1, 0);
break;
n++;
}
ot = dcommontype(s, ot, t);
+ xt = ot - 2*widthptr;
ot = dsymptr(s, ot, s, ot+widthptr+2*4);
ot = duint32(s, ot, n);
ot = duint32(s, ot, n);
}
break;
}
-
+ ot = dextratype(s, ot, t, xt);
ggloblsym(s, ot, dupok);
return s;
}
last = nil;
datap = nil;
- for(h=0; h<NHASH; h++) {
- for(s=hash[h]; s!=S; s=s->hash){
- if(!s->reachable || s->special)
- continue;
- if(STEXT < s->type && s->type < SXREF) {
- if(last == nil)
- datap = s;
- else
- last->next = s;
- s->next = nil;
- last = s;
- }
+ for(s=allsym; s!=S; s=s->allsym) {
+ if(!s->reachable || s->special)
+ continue;
+ if(STEXT < s->type && s->type < SXREF) {
+ if(last == nil)
+ datap = s;
+ else
+ last->next = s;
+ s->next = nil;
+ last = s;
}
}
{
Sym *s;
- s = lookup(n, 0);
- if (s->size == 0) {
+ s = rlookup(n, 0);
+ if (s == nil || s->size == 0) {
diag("dwarf: missing type: %s", n);
errorexit();
}
if (strncmp(s, "go.string.", 10) == 0)
return;
- if (strncmp(s, "string.", 7) == 0)
- return;
- if (strncmp(s, "type._.", 7) == 0)
- return;
if (strncmp(s, "type.", 5) == 0 && strcmp(s, "type.*") != 0) {
defgotype(sym);
{
vlong infoe;
DWDie* die;
-
+return;
// For diagnostic messages.
newattr(&dwtypes, DW_AT_name, DW_CLS_STRING, strlen("dwtypes"), "dwtypes");
elfdynhash(void)
{
Sym *s, *sy;
- int i, h, nbucket, b;
+ int i, nbucket, b;
uchar *pc;
uint32 hc, g;
uint32 *chain, *buckets;
}
memset(chain, 0, nsym * sizeof(uint32));
memset(buckets, 0, nbucket * sizeof(uint32));
- for(h = 0; h<NHASH; h++) {
- for(sy=hash[h]; sy!=S; sy=sy->hash) {
- if (sy->dynid <= 0)
- continue;
-
- hc = 0;
- name = sy->dynimpname;
- if(name == nil)
- name = sy->name;
- for(pc = (uchar*)name; *pc; pc++) {
- hc = (hc<<4) + *pc;
- g = hc & 0xf0000000;
- hc ^= g >> 24;
- hc &= ~g;
- }
-
- b = hc % nbucket;
- chain[sy->dynid] = buckets[b];
- buckets[b] = sy->dynid;
+ for(sy=allsym; sy!=S; sy=sy->allsym) {
+ if (sy->dynid <= 0)
+ continue;
+
+ hc = 0;
+ name = sy->dynimpname;
+ if(name == nil)
+ name = sy->name;
+ for(pc = (uchar*)name; *pc; pc++) {
+ hc = (hc<<4) + *pc;
+ g = hc & 0xf0000000;
+ hc ^= g >> 24;
+ hc &= ~g;
}
+
+ b = hc % nbucket;
+ chain[sy->dynid] = buckets[b];
+ buckets[b] = sy->dynid;
}
adduint32(s, nbucket);
else
last->next = nil;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->hash)
+ for(s = allsym; s != S; s = s->allsym)
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) {
+ for(s = allsym; s != S; s = s->allsym) {
if(strncmp(s->name, "weak.", 5) == 0) {
- t = lookup(s->name+5, s->version);
- if(t->type != 0 && t->reachable) {
+ t = rlookup(s->name+5, s->version);
+ if(t && t->type != 0 && t->reachable) {
s->value = t->value;
s->type = t->type;
} else {
diag("truncated object file: %s", pn);
}
-Sym*
-lookup(char *symb, int v)
+static Sym*
+_lookup(char *symb, int v, int creat)
{
Sym *s;
char *p;
// not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it.
h &= 0xffffff;
h %= NHASH;
+ c = symb[0];
for(s = hash[h]; s != S; s = s->hash)
- if(s->version == v)
if(memcmp(s->name, symb, l) == 0)
return s;
+ if(!creat)
+ return nil;
s = mal(sizeof(*s));
if(debug['v'] > 1)
s->size = 0;
hash[h] = s;
nsymbol++;
+
+ s->allsym = allsym;
+ allsym = s;
return s;
}
+Sym*
+lookup(char *name, int v)
+{
+ return _lookup(name, v, 1);
+}
+
+// read-only lookup
+Sym*
+rlookup(char *name, int v)
+{
+ return _lookup(name, v, 0);
+}
+
void
copyhistfrog(char *buf, int nbuf)
{
void
undef(void)
{
- int i;
Sym *s;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->hash)
+ for(s = allsym; s != S; s = s->allsym)
if(s->type == SXREF)
diag("%s(%d): not defined", s->name, s->version);
}
SDYNIMPORT,
SSUB = 1<<8, /* sub-symbol, linked from parent via ->sub list */
+
+ NHASH = 100003,
};
typedef struct Library Library;
EXTERN int libraryp;
EXTERN int nlibrary;
EXTERN Sym* hash[NHASH];
+EXTERN Sym* allsym;
EXTERN Sym* histfrog[MAXHIST];
EXTERN uchar fnuxi8[8];
EXTERN uchar fnuxi4[4];
void histtoauto(void);
void collapsefrog(Sym *s);
Sym* lookup(char *symb, int v);
+Sym* rlookup(char *symb, int v);
void nuxiinit(void);
int find1(int32 l, int c);
int find2(int32 l, int c);
Imp *m;
Dll *d;
Sym *s, *dynamic;
- int i;
dr = nil;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->hash) {
+ for(s = allsym; s != S; s = s->allsym) {
if(!s->reachable || !s->dynimpname || s->dynexport)
continue;
for(d = dr; d != nil; d = d->next) {
static void
initdynexport(void)
{
- int i;
Sym *s;
nexport = 0;
- for(i=0; i<NHASH; i++)
- for(s = hash[i]; s != S; s = s->hash) {
+ for(s = allsym; s != S; s = s->allsym) {
if(!s->reachable || !s->dynimpname || !s->dynexport)
continue;
if(nexport+1 > sizeof(dexport)/sizeof(dexport[0])) {
void
symtab(void)
{
- int32 h;
Sym *s;
// Define these so that they'll get put into the symbol table.
s->size = 0;
s->reachable = 1;
- s = lookup("string.*", 0);
- s->type = SSTRING;
- s->size = 0;
- s->reachable = 1;
-
s = lookup("go.string.*", 0);
s->type = SGOSTRING;
s->size = 0;
// within a type they sort by size, so the .* symbols
// just defined above will be first.
// hide the specific symbols.
- for(h=0; h<NHASH; h++) {
- for(s=hash[h]; s!=S; s=s->hash){
- if(!s->reachable || s->special || s->type != SRODATA)
- continue;
- if(strncmp(s->name, "type.", 5) == 0) {
- s->type = STYPE;
- s->hide = 1;
- }
- if(strncmp(s->name, "string.", 7) == 0) {
- s->type = SSTRING;
- s->hide = 1;
- }
- if(strncmp(s->name, "go.string.", 10) == 0) {
- s->type = SGOSTRING;
- s->hide = 1;
- }
+ for(s = allsym; s != S; s = s->allsym) {
+ if(!s->reachable || s->special || s->type != SRODATA)
+ continue;
+ if(strncmp(s->name, "type.", 5) == 0) {
+ s->type = STYPE;
+ s->hide = 1;
+ }
+ if(strncmp(s->name, "go.string.", 10) == 0) {
+ s->type = SGOSTRING;
+ s->hide = 1;
}
}