// accumulate all type information from .6 files.
// check for inconsistencies.
-// define gotypestrings variable if needed.
-// define gotypesigs variable if needed.
// TODO:
-// include type info for non-exported types.
// generate debugging section in binary.
// once the dust settles, try to move some code to
// libmach, so that other linkers and ar can share.
return strcmp(a->name, b->name);
}
-// if there is an undefined reference to gotypestrings,
-// create it. c declaration is
-// extern char gotypestrings[];
-// ironically, gotypestrings is a c variable, because there
-// is no way to forward declare a string in go.
-void
-definetypestrings(void)
-{
- int i, j, len, n, w;
- char *p;
- Import **all, *x;
- Fmt f;
- Prog *prog;
- Sym *s;
-
- if(debug['g'])
- return;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f definetypestrings\n", cputime());
-
- s = lookup("gotypestrings", 0);
- if(s->type == 0)
- return;
- if(s->type != SXREF) {
- diag("gotypestrings already defined");
- return;
- }
- s->type = SDATA;
-
- // make a list of all the type exports
- n = 0;
- for(i=0; i<NIHASH; i++)
- for(x=ihash[i]; x; x=x->hash)
- if(strcmp(x->prefix, "type") == 0)
- n++;
- all = mal(n*sizeof all[0]);
- j = 0;
- for(i=0; i<NIHASH; i++)
- for(x=ihash[i]; x; x=x->hash)
- if(strcmp(x->prefix, "type") == 0)
- all[j++] = x;
-
- // sort them by name
- qsort(all, n, sizeof all[0], importcmp);
-
- // make a big go string containing all the types
- fmtstrinit(&f);
- fmtprint(&f, "xxxx"); // 4-byte length
- for(i=0; i<n; i++) {
- p = strchr(all[i]->def, '\n');
- if(p)
- len = p - all[i]->def;
- else
- len = strlen(all[i]->def);
- fmtprint(&f, "%s %.*s\n", all[i]->name, utfnlen(all[i]->def, len), all[i]->def);
- }
- p = fmtstrflush(&f);
- n = strlen(p);
- s->value = n;
-
- // go strings begin with 4-byte length.
- // amd64 is little-endian.
- len = n - 4;
- p[0] = len;
- p[1] = len >> 8;
- p[2] = len >> 16;
- p[3] = len >> 24;
-
- // have data, need to create linker representation.
- // linker stores big data as sequence of pieces
- // with int8 length, so break p into 100-byte chunks.
- // (had to add D_SBIG even to do that; the compiler
- // would have generated 8-byte chunks.)
- for(i=0; i<n; i+=100) {
- w = 100;
- if(w > n - i)
- w = n - i;
- prog = newdata(s, i, w, D_EXTERN);
- prog->to.type = D_SBIG;
- prog->to.sbig = p + i;
- }
-
- if(debug['v'])
- Bprint(&bso, "%5.2f typestrings %d\n", cputime(), n);
-}
-
-// if there is an undefined reference to gotypesigs, create it.
-// c declaration is
-// extern Sigt *gotypesigs[];
-// extern int ngotypesigs;
-// used by sys.unreflect runtime.
-void
-definetypesigs(void)
-{
- int i, j, n;
- Sym **all, *s, *x;
- Prog *prog;
-
- if(debug['g'])
- return;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f definetypesigs\n", cputime());
-
- s = lookup("gotypesigs", 0);
- if(s->type == 0)
- return;
- if(s->type != SXREF) {
- diag("gotypesigs already defined");
- return;
- }
- s->type = SDATA;
-
- // make a list of all the sigt symbols.
- n = 0;
- for(i=0; i<NHASH; i++)
- for(x = hash[i]; x; x=x->link)
- if(memcmp(x->name, "sigtĀ·", 6) == 0 && x->type != Sxxx)
- n++;
- all = mal(n*sizeof all[0]);
- j = 0;
- for(i=0; i<NHASH; i++)
- for(x = hash[i]; x; x=x->link)
- if(memcmp(x->name, "sigtĀ·", 6) == 0 && x->type != Sxxx)
- all[j++] = x;
-
- // sort them by name
- qsort(all, n, sizeof all[0], symcmp);
-
- // emit array as sequence of references.
- for(i=0; i<n; i++) {
- prog = newdata(s, PtrSize*i, PtrSize, D_EXTERN);
- prog->to.type = D_ADDR;
- prog->to.index = D_EXTERN;
- prog->to.sym = all[i];
- }
- s->value = PtrSize*n;
- if(n == 0)
- s->value = 1; // must have non-zero size or 6l complains
-
- // emit count
- s = lookup("ngotypesigs", 0);
- s->type = SDATA;
- s->value = sizeof(int32);
- prog = newdata(s, 0, sizeof(int32), D_EXTERN);
- prog->to.offset = n;
-
- if(debug['v'])
- Bprint(&bso, "%5.2f typesigs %d\n", cputime(), n);
-}
-
static void mark(Sym*);
static int markdepth;