github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/cmd/ld/go.c (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // go-specific code shared across loaders (5l, 6l, 8l).
     6  
     7  #include	"l.h"
     8  #include	"../ld/lib.h"
     9  
    10  // accumulate all type information from .6 files.
    11  // check for inconsistencies.
    12  
    13  // TODO:
    14  //	generate debugging section in binary.
    15  //	once the dust settles, try to move some code to
    16  //		libmach, so that other linkers and ar can share.
    17  
    18  /*
    19   *	package import data
    20   */
    21  typedef struct Import Import;
    22  struct Import
    23  {
    24  	Import *hash;	// next in hash table
    25  	char *prefix;	// "type", "var", "func", "const"
    26  	char *name;
    27  	char *def;
    28  	char *file;
    29  };
    30  enum {
    31  	NIHASH = 1024
    32  };
    33  static Import *ihash[NIHASH];
    34  static int nimport;
    35  static void imported(char *pkg, char *import);
    36  
    37  static int
    38  hashstr(char *name)
    39  {
    40  	uint32 h;
    41  	char *cp;
    42  
    43  	h = 0;
    44  	for(cp = name; *cp; h += *cp++)
    45  		h *= 1119;
    46  	h &= 0xffffff;
    47  	return h;
    48  }
    49  
    50  static Import *
    51  ilookup(char *name)
    52  {
    53  	int h;
    54  	Import *x;
    55  
    56  	h = hashstr(name) % NIHASH;
    57  	for(x=ihash[h]; x; x=x->hash)
    58  		if(x->name[0] == name[0] && strcmp(x->name, name) == 0)
    59  			return x;
    60  	x = mal(sizeof *x);
    61  	x->name = estrdup(name);
    62  	x->hash = ihash[h];
    63  	ihash[h] = x;
    64  	nimport++;
    65  	return x;
    66  }
    67  
    68  static void loadpkgdata(char*, char*, char*, int);
    69  static void loadcgo(char*, char*, char*, int);
    70  static int parsemethod(char**, char*, char**);
    71  static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**);
    72  
    73  void
    74  ldpkg(Biobuf *f, char *pkg, int64 len, char *filename, int whence)
    75  {
    76  	char *data, *p0, *p1, *name;
    77  
    78  	if(debug['g'])
    79  		return;
    80  
    81  	if((int)len != len) {
    82  		fprint(2, "%s: too much pkg data in %s\n", argv0, filename);
    83  		if(debug['u'])
    84  			errorexit();
    85  		return;
    86  	}
    87  	data = mal(len+1);
    88  	if(Bread(f, data, len) != len) {
    89  		fprint(2, "%s: short pkg read %s\n", argv0, filename);
    90  		if(debug['u'])
    91  			errorexit();
    92  		return;
    93  	}
    94  	data[len] = '\0';
    95  
    96  	// first \n$$ marks beginning of exports - skip rest of line
    97  	p0 = strstr(data, "\n$$");
    98  	if(p0 == nil) {
    99  		if(debug['u'] && whence != ArchiveObj) {
   100  			fprint(2, "%s: cannot find export data in %s\n", argv0, filename);
   101  			errorexit();
   102  		}
   103  		return;
   104  	}
   105  	p0 += 3;
   106  	while(*p0 != '\n' && *p0 != '\0')
   107  		p0++;
   108  
   109  	// second marks end of exports / beginning of local data
   110  	p1 = strstr(p0, "\n$$");
   111  	if(p1 == nil) {
   112  		fprint(2, "%s: cannot find end of exports in %s\n", argv0, filename);
   113  		if(debug['u'])
   114  			errorexit();
   115  		return;
   116  	}
   117  	while(p0 < p1 && (*p0 == ' ' || *p0 == '\t' || *p0 == '\n'))
   118  		p0++;
   119  	if(p0 < p1) {
   120  		if(strncmp(p0, "package ", 8) != 0) {
   121  			fprint(2, "%s: bad package section in %s - %s\n", argv0, filename, p0);
   122  			if(debug['u'])
   123  				errorexit();
   124  			return;
   125  		}
   126  		p0 += 8;
   127  		while(p0 < p1 && (*p0 == ' ' || *p0 == '\t' || *p0 == '\n'))
   128  			p0++;
   129  		name = p0;
   130  		while(p0 < p1 && *p0 != ' ' && *p0 != '\t' && *p0 != '\n')
   131  			p0++;
   132  		if(debug['u'] && whence != ArchiveObj &&
   133  		   (p0+6 > p1 || memcmp(p0, " safe\n", 6) != 0)) {
   134  			fprint(2, "%s: load of unsafe package %s\n", argv0, filename);
   135  			nerrors++;
   136  			errorexit();
   137  		}
   138  		if(p0 < p1) {
   139  			if(*p0 == '\n')
   140  				*p0++ = '\0';
   141  			else {
   142  				*p0++ = '\0';
   143  				while(p0 < p1 && *p0++ != '\n')
   144  					;
   145  			}
   146  		}
   147  		if(strcmp(pkg, "main") == 0 && strcmp(name, "main") != 0) {
   148  			fprint(2, "%s: %s: not package main (package %s)\n", argv0, filename, name);
   149  			nerrors++;
   150  			errorexit();
   151  		}
   152  		loadpkgdata(filename, pkg, p0, p1 - p0);
   153  	}
   154  	
   155  	// __.PKGDEF has no cgo section - those are in the C compiler-generated object files.
   156  	if(whence == Pkgdef)
   157  		return;
   158  
   159  	// look for cgo section
   160  	p0 = strstr(p1, "\n$$  // cgo");
   161  	if(p0 != nil) {
   162  		p0 = strchr(p0+1, '\n');
   163  		if(p0 == nil) {
   164  			fprint(2, "%s: found $$ // cgo but no newline in %s\n", argv0, filename);
   165  			if(debug['u'])
   166  				errorexit();
   167  			return;
   168  		}
   169  		p1 = strstr(p0, "\n$$");
   170  		if(p1 == nil)
   171  			p1 = strstr(p0, "\n!\n");
   172  		if(p1 == nil) {
   173  			fprint(2, "%s: cannot find end of // cgo section in %s\n", argv0, filename);
   174  			if(debug['u'])
   175  				errorexit();
   176  			return;
   177  		}
   178  		loadcgo(filename, pkg, p0 + 1, p1 - (p0+1));
   179  	}
   180  }
   181  
   182  static void
   183  loadpkgdata(char *file, char *pkg, char *data, int len)
   184  {
   185  	char *p, *ep, *prefix, *name, *def;
   186  	Import *x;
   187  
   188  	file = estrdup(file);
   189  	p = data;
   190  	ep = data + len;
   191  	while(parsepkgdata(file, pkg, &p, ep, &prefix, &name, &def) > 0) {
   192  		x = ilookup(name);
   193  		if(x->prefix == nil) {
   194  			x->prefix = prefix;
   195  			x->def = estrdup(def);
   196  			x->file = file;
   197  		} else if(strcmp(x->prefix, prefix) != 0) {
   198  			fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
   199  			fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
   200  			fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
   201  			nerrors++;
   202  		} else if(strcmp(x->def, def) != 0) {
   203  			fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
   204  			fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
   205  			fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
   206  			nerrors++;
   207  		}
   208  		free(name);
   209  		free(def);
   210  	}
   211  	free(file);
   212  }
   213  
   214  static int
   215  parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp)
   216  {
   217  	char *p, *prefix, *name, *def, *edef, *meth;
   218  	int n, inquote;
   219  
   220  	// skip white space
   221  	p = *pp;
   222  loop:
   223  	while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n'))
   224  		p++;
   225  	if(p == ep || strncmp(p, "$$\n", 3) == 0)
   226  		return 0;
   227  
   228  	// prefix: (var|type|func|const)
   229  	prefix = p;
   230  	if(p + 7 > ep)
   231  		return -1;
   232  	if(strncmp(p, "var ", 4) == 0)
   233  		p += 4;
   234  	else if(strncmp(p, "type ", 5) == 0)
   235  		p += 5;
   236  	else if(strncmp(p, "func ", 5) == 0)
   237  		p += 5;
   238  	else if(strncmp(p, "const ", 6) == 0)
   239  		p += 6;
   240  	else if(strncmp(p, "import ", 7) == 0) {
   241  		p += 7;
   242  		while(p < ep && *p != ' ')
   243  			p++;
   244  		p++;
   245  		name = p;
   246  		while(p < ep && *p != '\n')
   247  			p++;
   248  		if(p >= ep) {
   249  			fprint(2, "%s: %s: confused in import line\n", argv0, file);
   250  			nerrors++;
   251  			return -1;
   252  		}
   253  		*p++ = '\0';
   254  		imported(pkg, name);
   255  		goto loop;
   256  	}
   257  	else {
   258  		fprint(2, "%s: %s: confused in pkg data near <<%.40s>>\n", argv0, file, prefix);
   259  		nerrors++;
   260  		return -1;
   261  	}
   262  	p[-1] = '\0';
   263  
   264  	// name: a.b followed by space
   265  	name = p;
   266  	inquote = 0;
   267  	while(p < ep) {
   268  		if (*p == ' ' && !inquote)
   269  			break;
   270  
   271  		if(*p == '\\')
   272  			p++;
   273  		else if(*p == '"')
   274  			inquote = !inquote;
   275  
   276  		p++;
   277  	}
   278  
   279  	if(p >= ep)
   280  		return -1;
   281  	*p++ = '\0';
   282  
   283  	// def: free form to new line
   284  	def = p;
   285  	while(p < ep && *p != '\n')
   286  		p++;
   287  	if(p >= ep)
   288  		return -1;
   289  	edef = p;
   290  	*p++ = '\0';
   291  
   292  	// include methods on successive lines in def of named type
   293  	while(parsemethod(&p, ep, &meth) > 0) {
   294  		*edef++ = '\n';	// overwrites '\0'
   295  		if(edef+1 > meth) {
   296  			// We want to indent methods with a single \t.
   297  			// 6g puts at least one char of indent before all method defs,
   298  			// so there will be room for the \t.  If the method def wasn't
   299  			// indented we could do something more complicated,
   300  			// but for now just diagnose the problem and assume
   301  			// 6g will keep indenting for us.
   302  			fprint(2, "%s: %s: expected methods to be indented %p %p %.10s\n", argv0,
   303  				file, edef, meth, meth);
   304  			nerrors++;
   305  			return -1;
   306  		}
   307  		*edef++ = '\t';
   308  		n = strlen(meth);
   309  		memmove(edef, meth, n);
   310  		edef += n;
   311  	}
   312  
   313  	name = expandpkg(name, pkg);
   314  	def = expandpkg(def, pkg);
   315  
   316  	// done
   317  	*pp = p;
   318  	*prefixp = prefix;
   319  	*namep = name;
   320  	*defp = def;
   321  	return 1;
   322  }
   323  
   324  static int
   325  parsemethod(char **pp, char *ep, char **methp)
   326  {
   327  	char *p;
   328  
   329  	// skip white space
   330  	p = *pp;
   331  	while(p < ep && (*p == ' ' || *p == '\t'))
   332  		p++;
   333  	if(p == ep)
   334  		return 0;
   335  
   336  	// might be a comment about the method
   337  	if(p + 2 < ep && strncmp(p, "//", 2) == 0)
   338  		goto useline;
   339  	
   340  	// if it says "func (", it's a method
   341  	if(p + 6 < ep && strncmp(p, "func (", 6) == 0)
   342  		goto useline;
   343  	return 0;
   344  
   345  useline:
   346  	// definition to end of line
   347  	*methp = p;
   348  	while(p < ep && *p != '\n')
   349  		p++;
   350  	if(p >= ep) {
   351  		fprint(2, "%s: lost end of line in method definition\n", argv0);
   352  		*pp = ep;
   353  		return -1;
   354  	}
   355  	*p++ = '\0';
   356  	*pp = p;
   357  	return 1;
   358  }
   359  
   360  static void
   361  loadcgo(char *file, char *pkg, char *p, int n)
   362  {
   363  	char *pend, *next, *p0, *q;
   364  	char *f[10], *local, *remote, *lib;
   365  	int nf;
   366  	LSym *s;
   367  
   368  	USED(file);
   369  	pend = p + n;
   370  	p0 = nil;
   371  	for(; p<pend; p=next) {
   372  		next = strchr(p, '\n');
   373  		if(next == nil)
   374  			next = "";
   375  		else
   376  			*next++ = '\0';
   377  
   378  		free(p0);
   379  		p0 = estrdup(p); // save for error message
   380  		nf = tokenize(p, f, nelem(f));
   381  		
   382  		if(strcmp(f[0], "cgo_import_dynamic") == 0) {
   383  			if(nf < 2 || nf > 4)
   384  				goto err;
   385  			
   386  			local = f[1];
   387  			remote = local;
   388  			if(nf > 2)
   389  				remote = f[2];
   390  			lib = "";
   391  			if(nf > 3)
   392  				lib = f[3];
   393  			
   394  			if(debug['d']) {
   395  				fprint(2, "%s: %s: cannot use dynamic imports with -d flag\n", argv0, file);
   396  				nerrors++;
   397  				return;
   398  			}
   399  		
   400  			if(strcmp(local, "_") == 0 && strcmp(remote, "_") == 0) {
   401  				// allow #pragma dynimport _ _ "foo.so"
   402  				// to force a link of foo.so.
   403  				havedynamic = 1;
   404  				adddynlib(lib);
   405  				continue;
   406  			}
   407  
   408  			local = expandpkg(local, pkg);
   409  			q = strchr(remote, '#');
   410  			if(q)
   411  				*q++ = '\0';
   412  			s = linklookup(ctxt, local, 0);
   413  			if(local != f[1])
   414  				free(local);
   415  			if(s->type == 0 || s->type == SXREF || s->type == SHOSTOBJ) {
   416  				s->dynimplib = lib;
   417  				s->extname = remote;
   418  				s->dynimpvers = q;
   419  				if(s->type != SHOSTOBJ)
   420  					s->type = SDYNIMPORT;
   421  				havedynamic = 1;
   422  			}
   423  			continue;
   424  		}
   425  		
   426  		if(strcmp(f[0], "cgo_import_static") == 0) {
   427  			if(nf != 2)
   428  				goto err;
   429  			local = f[1];
   430  			s = linklookup(ctxt, local, 0);
   431  			s->type = SHOSTOBJ;
   432  			s->size = 0;
   433  			continue;
   434  		}
   435  
   436  		if(strcmp(f[0], "cgo_export_static") == 0 || strcmp(f[0], "cgo_export_dynamic") == 0) {
   437  			// TODO: Remove once we know Windows is okay.
   438  			if(strcmp(f[0], "cgo_export_static") == 0 && HEADTYPE == Hwindows)
   439  				continue;
   440  
   441  			if(nf < 2 || nf > 3)
   442  				goto err;
   443  			local = f[1];
   444  			if(nf > 2)
   445  				remote = f[2];
   446  			else
   447  				remote = local;
   448  			local = expandpkg(local, pkg);
   449  			s = linklookup(ctxt, local, 0);
   450  
   451  			if(flag_shared && s == linklookup(ctxt, "main", 0))
   452  				continue;
   453  
   454  			// export overrides import, for openbsd/cgo.
   455  			// see issue 4878.
   456  			if(s->dynimplib != nil) {
   457  				s->dynimplib = nil;
   458  				s->extname = nil;
   459  				s->dynimpvers = nil;
   460  				s->type = 0;
   461  			}
   462  
   463  			if(s->cgoexport == 0) {
   464  				s->extname = remote;
   465  				if(ndynexp%32 == 0)
   466  					dynexp = erealloc(dynexp, (ndynexp+32)*sizeof dynexp[0]);
   467  				dynexp[ndynexp++] = s;
   468  			} else if(strcmp(s->extname, remote) != 0) {
   469  				fprint(2, "%s: conflicting cgo_export directives: %s as %s and %s\n", argv0, s->name, s->extname, remote);
   470  				nerrors++;
   471  				return;
   472  			}
   473  			if(strcmp(f[0], "cgo_export_static") == 0)
   474  				s->cgoexport |= CgoExportStatic;
   475  			else
   476  				s->cgoexport |= CgoExportDynamic;
   477  			if(local != f[1])
   478  				free(local);
   479  			continue;
   480  		}
   481  		
   482  		if(strcmp(f[0], "cgo_dynamic_linker") == 0) {
   483  			if(nf != 2)
   484  				goto err;
   485  			
   486  			if(!debug['I']) { // not overridden by command line
   487  				if(interpreter != nil && strcmp(interpreter, f[1]) != 0) {
   488  					fprint(2, "%s: conflict dynlinker: %s and %s\n", argv0, interpreter, f[1]);
   489  					nerrors++;
   490  					return;
   491  				}
   492  				free(interpreter);
   493  				interpreter = estrdup(f[1]);
   494  			}
   495  			continue;
   496  		}
   497  		
   498  		if(strcmp(f[0], "cgo_ldflag") == 0) {
   499  			if(nf != 2)
   500  				goto err;
   501  			if(nldflag%32 == 0)
   502  				ldflag = erealloc(ldflag, (nldflag+32)*sizeof ldflag[0]);
   503  			ldflag[nldflag++] = estrdup(f[1]);
   504  			continue;
   505  		}
   506  	}
   507  	free(p0);
   508  	return;
   509  
   510  err:
   511  	fprint(2, "%s: %s: invalid dynimport line: %s\n", argv0, file, p0);
   512  	nerrors++;
   513  }
   514  
   515  static LSym *markq;
   516  static LSym *emarkq;
   517  
   518  static void
   519  mark1(LSym *s, LSym *parent)
   520  {
   521  	if(s == S || s->reachable)
   522  		return;
   523  	if(strncmp(s->name, "go.weak.", 8) == 0)
   524  		return;
   525  	s->reachable = 1;
   526  	s->reachparent = parent;
   527  	if(markq == nil)
   528  		markq = s;
   529  	else
   530  		emarkq->queue = s;
   531  	emarkq = s;
   532  }
   533  
   534  void
   535  mark(LSym *s)
   536  {
   537  	mark1(s, nil);
   538  }
   539  
   540  static void
   541  markflood(void)
   542  {
   543  	Auto *a;
   544  	LSym *s;
   545  	int i;
   546  	
   547  	for(s=markq; s!=S; s=s->queue) {
   548  		if(s->type == STEXT) {
   549  			if(debug['v'] > 1)
   550  				Bprint(&bso, "marktext %s\n", s->name);
   551  			for(a=s->autom; a; a=a->link)
   552  				mark1(a->gotype, s);
   553  		}
   554  		for(i=0; i<s->nr; i++)
   555  			mark1(s->r[i].sym, s);
   556  		if(s->pcln) {
   557  			for(i=0; i<s->pcln->nfuncdata; i++)
   558  				mark1(s->pcln->funcdata[i], s);
   559  		}
   560  		mark1(s->gotype, s);
   561  		mark1(s->sub, s);
   562  		mark1(s->outer, s);
   563  	}
   564  }
   565  
   566  static char*
   567  markextra[] =
   568  {
   569  	"runtime.morestack",
   570  	"runtime.morestackx",
   571  
   572  	"runtime.morestack00",
   573  	"runtime.morestack10",
   574  	"runtime.morestack01",
   575  	"runtime.morestack11",
   576  
   577  	"runtime.morestack8",
   578  	"runtime.morestack16",
   579  	"runtime.morestack24",
   580  	"runtime.morestack32",
   581  	"runtime.morestack40",
   582  	"runtime.morestack48",
   583  	
   584  	// on arm, lock in the div/mod helpers too
   585  	"_div",
   586  	"_divu",
   587  	"_mod",
   588  	"_modu",
   589  };
   590  
   591  void
   592  deadcode(void)
   593  {
   594  	int i;
   595  	LSym *s, *last, *p;
   596  	Fmt fmt;
   597  
   598  	if(debug['v'])
   599  		Bprint(&bso, "%5.2f deadcode\n", cputime());
   600  
   601  	mark(linklookup(ctxt, INITENTRY, 0));
   602  	for(i=0; i<nelem(markextra); i++)
   603  		mark(linklookup(ctxt, markextra[i], 0));
   604  
   605  	for(i=0; i<ndynexp; i++)
   606  		mark(dynexp[i]);
   607  
   608  	markflood();
   609  	
   610  	// keep each beginning with 'typelink.' if the symbol it points at is being kept.
   611  	for(s = ctxt->allsym; s != S; s = s->allsym) {
   612  		if(strncmp(s->name, "go.typelink.", 12) == 0)
   613  			s->reachable = s->nr==1 && s->r[0].sym->reachable;
   614  	}
   615  
   616  	// remove dead text but keep file information (z symbols).
   617  	last = nil;
   618  	for(s = ctxt->textp; s != nil; s = s->next) {
   619  		if(!s->reachable)
   620  			continue;
   621  		// NOTE: Removing s from old textp and adding to new, shorter textp.
   622  		if(last == nil)
   623  			ctxt->textp = s;
   624  		else
   625  			last->next = s;
   626  		last = s;
   627  	}
   628  	if(last == nil)
   629  		ctxt->textp = nil;
   630  	else
   631  		last->next = nil;
   632  	
   633  	for(s = ctxt->allsym; s != S; s = s->allsym)
   634  		if(strncmp(s->name, "go.weak.", 8) == 0) {
   635  			s->special = 1;  // do not lay out in data segment
   636  			s->reachable = 1;
   637  			s->hide = 1;
   638  		}
   639  	
   640  	// record field tracking references
   641  	fmtstrinit(&fmt);
   642  	for(s = ctxt->allsym; s != S; s = s->allsym) {
   643  		if(strncmp(s->name, "go.track.", 9) == 0) {
   644  			s->special = 1;  // do not lay out in data segment
   645  			s->hide = 1;
   646  			if(s->reachable) {
   647  				fmtprint(&fmt, "%s", s->name+9);
   648  				for(p=s->reachparent; p; p=p->reachparent)
   649  					fmtprint(&fmt, "\t%s", p->name);
   650  				fmtprint(&fmt, "\n");
   651  			}
   652  			s->type = SCONST;
   653  			s->value = 0;
   654  		}
   655  	}
   656  	if(tracksym == nil)
   657  		return;
   658  	s = linklookup(ctxt, tracksym, 0);
   659  	if(!s->reachable)
   660  		return;
   661  	addstrdata(tracksym, fmtstrflush(&fmt));
   662  }
   663  
   664  void
   665  doweak(void)
   666  {
   667  	LSym *s, *t;
   668  
   669  	// resolve weak references only if
   670  	// target symbol will be in binary anyway.
   671  	for(s = ctxt->allsym; s != S; s = s->allsym) {
   672  		if(strncmp(s->name, "go.weak.", 8) == 0) {
   673  			t = linkrlookup(ctxt, s->name+8, s->version);
   674  			if(t && t->type != 0 && t->reachable) {
   675  				s->value = t->value;
   676  				s->type = t->type;
   677  				s->outer = t;
   678  			} else {
   679  				s->type = SCONST;
   680  				s->value = 0;
   681  			}
   682  			continue;
   683  		}
   684  	}
   685  }
   686  
   687  void
   688  addexport(void)
   689  {
   690  	int i;
   691  	
   692  	if(HEADTYPE == Hdarwin)
   693  		return;
   694  
   695  	for(i=0; i<ndynexp; i++)
   696  		adddynsym(ctxt, dynexp[i]);
   697  }
   698  
   699  /* %Z from gc, for quoting import paths */
   700  int
   701  Zconv(Fmt *fp)
   702  {
   703  	Rune r;
   704  	char *s, *se;
   705  	int n;
   706  
   707  	s = va_arg(fp->args, char*);
   708  	if(s == nil)
   709  		return fmtstrcpy(fp, "<nil>");
   710  
   711  	se = s + strlen(s);
   712  
   713  	// NOTE: Keep in sync with ../gc/go.c:/^Zconv.
   714  	while(s < se) {
   715  		n = chartorune(&r, s);
   716  		s += n;
   717  		switch(r) {
   718  		case Runeerror:
   719  			if(n == 1) {
   720  				fmtprint(fp, "\\x%02x", (uchar)*(s-1));
   721  				break;
   722  			}
   723  			// fall through
   724  		default:
   725  			if(r < ' ') {
   726  				fmtprint(fp, "\\x%02x", r);
   727  				break;
   728  			}
   729  			fmtrune(fp, r);
   730  			break;
   731  		case '\t':
   732  			fmtstrcpy(fp, "\\t");
   733  			break;
   734  		case '\n':
   735  			fmtstrcpy(fp, "\\n");
   736  			break;
   737  		case '\"':
   738  		case '\\':
   739  			fmtrune(fp, '\\');
   740  			fmtrune(fp, r);
   741  			break;
   742  		case 0xFEFF: // BOM, basically disallowed in source code
   743  			fmtstrcpy(fp, "\\uFEFF");
   744  			break;
   745  		}
   746  	}
   747  	return 0;
   748  }
   749  
   750  
   751  typedef struct Pkg Pkg;
   752  struct Pkg
   753  {
   754  	uchar mark;
   755  	uchar checked;
   756  	Pkg *next;
   757  	char *path;
   758  	Pkg **impby;
   759  	int nimpby;
   760  	int mimpby;
   761  	Pkg *all;
   762  };
   763  
   764  static Pkg *phash[1024];
   765  static Pkg *pkgall;
   766  
   767  static Pkg*
   768  getpkg(char *path)
   769  {
   770  	Pkg *p;
   771  	int h;
   772  	
   773  	h = hashstr(path) % nelem(phash);
   774  	for(p=phash[h]; p; p=p->next)
   775  		if(strcmp(p->path, path) == 0)
   776  			return p;
   777  	p = mal(sizeof *p);
   778  	p->path = estrdup(path);
   779  	p->next = phash[h];
   780  	phash[h] = p;
   781  	p->all = pkgall;
   782  	pkgall = p;
   783  	return p;
   784  }
   785  
   786  static void
   787  imported(char *pkg, char *import)
   788  {
   789  	Pkg *p, *i;
   790  	
   791  	// everyone imports runtime, even runtime.
   792  	if(strcmp(import, "\"runtime\"") == 0)
   793  		return;
   794  
   795  	pkg = smprint("\"%Z\"", pkg);  // turn pkg path into quoted form, freed below
   796  	p = getpkg(pkg);
   797  	i = getpkg(import);
   798  	if(i->nimpby >= i->mimpby) {
   799  		i->mimpby *= 2;
   800  		if(i->mimpby == 0)
   801  			i->mimpby = 16;
   802  		i->impby = erealloc(i->impby, i->mimpby*sizeof i->impby[0]);
   803  	}
   804  	i->impby[i->nimpby++] = p;
   805  	free(pkg);
   806  }
   807  
   808  static Pkg*
   809  cycle(Pkg *p)
   810  {
   811  	int i;
   812  	Pkg *bad;
   813  
   814  	if(p->checked)
   815  		return 0;
   816  
   817  	if(p->mark) {
   818  		nerrors++;
   819  		print("import cycle:\n");
   820  		print("\t%s\n", p->path);
   821  		return p;
   822  	}
   823  	p->mark = 1;
   824  	for(i=0; i<p->nimpby; i++) {
   825  		if((bad = cycle(p->impby[i])) != nil) {
   826  			p->mark = 0;
   827  			p->checked = 1;
   828  			print("\timports %s\n", p->path);
   829  			if(bad == p)
   830  				return nil;
   831  			return bad;
   832  		}
   833  	}
   834  	p->checked = 1;
   835  	p->mark = 0;
   836  	return 0;
   837  }
   838  
   839  void
   840  importcycles(void)
   841  {
   842  	Pkg *p;
   843  	
   844  	for(p=pkgall; p; p=p->all)
   845  		cycle(p);
   846  }
   847  
   848  void
   849  setlinkmode(char *arg)
   850  {
   851  	if(strcmp(arg, "internal") == 0)
   852  		linkmode = LinkInternal;
   853  	else if(strcmp(arg, "external") == 0)
   854  		linkmode = LinkExternal;
   855  	else if(strcmp(arg, "auto") == 0)
   856  		linkmode = LinkAuto;
   857  	else {
   858  		fprint(2, "unknown link mode -linkmode %s\n", arg);
   859  		errorexit();
   860  	}
   861  }