github.com/golang-haiku/go-1.4.3@v0.0.0-20190609233734-1f5ae41cc308/src/cmd/ld/lib.c (about)

     1  // Derived from Inferno utils/6l/obj.c and utils/6l/span.c
     2  // http://code.google.com/p/inferno-os/source/browse/utils/6l/obj.c
     3  // http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c
     4  //
     5  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     6  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     7  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     8  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     9  //	Portions Copyright © 2004,2006 Bruce Ellis
    10  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    11  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    12  //	Portions Copyright © 2009 The Go Authors.  All rights reserved.
    13  //
    14  // Permission is hereby granted, free of charge, to any person obtaining a copy
    15  // of this software and associated documentation files (the "Software"), to deal
    16  // in the Software without restriction, including without limitation the rights
    17  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    18  // copies of the Software, and to permit persons to whom the Software is
    19  // furnished to do so, subject to the following conditions:
    20  //
    21  // The above copyright notice and this permission notice shall be included in
    22  // all copies or substantial portions of the Software.
    23  //
    24  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    25  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    26  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    27  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    28  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    29  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    30  // THE SOFTWARE.
    31  
    32  #include	"l.h"
    33  #include	"lib.h"
    34  #include	"../ld/elf.h"
    35  #include	"../ld/dwarf.h"
    36  #include	"../../runtime/stack.h"
    37  #include	"../../runtime/funcdata.h"
    38  
    39  #include	<ar.h>
    40  #if !(defined(_WIN32) || defined(PLAN9))
    41  #include	<sys/stat.h>
    42  #endif
    43  
    44  enum
    45  {
    46  	// Whether to assume that the external linker is "gold"
    47  	// (http://sourceware.org/ml/binutils/2008-03/msg00162.html).
    48  	AssumeGoldLinker = 0,
    49  };
    50  
    51  int iconv(Fmt*);
    52  
    53  char	symname[]	= SYMDEF;
    54  char	pkgname[]	= "__.PKGDEF";
    55  static int	cout = -1;
    56  
    57  extern int	version;
    58  
    59  // Set if we see an object compiled by the host compiler that is not
    60  // from a package that is known to support internal linking mode.
    61  static int	externalobj = 0;
    62  
    63  static	void	hostlinksetup(void);
    64  
    65  char*	goroot;
    66  char*	goarch;
    67  char*	goos;
    68  char*	theline;
    69  
    70  void
    71  Lflag(char *arg)
    72  {
    73  	char **p;
    74  
    75  	if(ctxt->nlibdir >= ctxt->maxlibdir) {
    76  		if (ctxt->maxlibdir == 0)
    77  			ctxt->maxlibdir = 8;
    78  		else
    79  			ctxt->maxlibdir *= 2;
    80  		p = erealloc(ctxt->libdir, ctxt->maxlibdir * sizeof(*p));
    81  		ctxt->libdir = p;
    82  	}
    83  	ctxt->libdir[ctxt->nlibdir++] = arg;
    84  }
    85  
    86  /*
    87   * Unix doesn't like it when we write to a running (or, sometimes,
    88   * recently run) binary, so remove the output file before writing it.
    89   * On Windows 7, remove() can force a subsequent create() to fail.
    90   * S_ISREG() does not exist on Plan 9.
    91   */
    92  static void
    93  mayberemoveoutfile(void) 
    94  {
    95  #if !(defined(_WIN32) || defined(PLAN9))
    96  	struct stat st;
    97  	if(lstat(outfile, &st) == 0 && !S_ISREG(st.st_mode))
    98  		return;
    99  #endif
   100  	remove(outfile);
   101  }
   102  
   103  void
   104  libinit(void)
   105  {
   106  	char *suffix, *suffixsep;
   107  
   108  	funcalign = FuncAlign;
   109  	fmtinstall('i', iconv);
   110  	fmtinstall('Y', Yconv);
   111  	fmtinstall('Z', Zconv);
   112  	mywhatsys();	// get goroot, goarch, goos
   113  
   114  	// add goroot to the end of the libdir list.
   115  	suffix = "";
   116  	suffixsep = "";
   117  	if(flag_installsuffix != nil) {
   118  		suffixsep = "_";
   119  		suffix = flag_installsuffix;
   120  	} else if(flag_race) {
   121  		suffixsep = "_";
   122  		suffix = "race";
   123  	}
   124  	Lflag(smprint("%s/pkg/%s_%s%s%s", goroot, goos, goarch, suffixsep, suffix));
   125  
   126  	mayberemoveoutfile();
   127  	cout = create(outfile, 1, 0775);
   128  	if(cout < 0) {
   129  		diag("cannot create %s: %r", outfile);
   130  		errorexit();
   131  	}
   132  
   133  	if(INITENTRY == nil) {
   134  		INITENTRY = mal(strlen(goarch)+strlen(goos)+20);
   135  		if(!flag_shared) {
   136  			sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
   137  		} else {
   138  			sprint(INITENTRY, "_rt0_%s_%s_lib", goarch, goos);
   139  		}
   140  	}
   141  	linklookup(ctxt, INITENTRY, 0)->type = SXREF;
   142  }
   143  
   144  void
   145  errorexit(void)
   146  {
   147  	if(cout >= 0) {
   148  		// For rmtemp run at atexit time on Windows.
   149  		close(cout);
   150  	}
   151  	if(nerrors) {
   152  		if(cout >= 0)
   153  			mayberemoveoutfile();
   154  		exits("error");
   155  	}
   156  	exits(0);
   157  }
   158  
   159  void
   160  loadinternal(char *name)
   161  {
   162  	char pname[1024];
   163  	int i, found;
   164  
   165  	found = 0;
   166  	for(i=0; i<ctxt->nlibdir; i++) {
   167  		snprint(pname, sizeof pname, "%s/%s.a", ctxt->libdir[i], name);
   168  		if(debug['v'])
   169  			Bprint(&bso, "searching for %s.a in %s\n", name, pname);
   170  		if(access(pname, AEXIST) >= 0) {
   171  			addlibpath(ctxt, "internal", "internal", pname, name);
   172  			found = 1;
   173  			break;
   174  		}
   175  	}
   176  	if(!found)
   177  		Bprint(&bso, "warning: unable to find %s.a\n", name);
   178  }
   179  
   180  void
   181  loadlib(void)
   182  {
   183  	int i, w, x;
   184  	LSym *s, *tlsg;
   185  	char* cgostrsym;
   186  
   187  	if(flag_shared) {
   188  		s = linklookup(ctxt, "runtime.islibrary", 0);
   189  		s->dupok = 1;
   190  		adduint8(ctxt, s, 1);
   191  	}
   192  
   193  	loadinternal("runtime");
   194  	if(thechar == '5')
   195  		loadinternal("math");
   196  	if(flag_race)
   197  		loadinternal("runtime/race");
   198  
   199  	for(i=0; i<ctxt->libraryp; i++) {
   200  		if(debug['v'] > 1)
   201  			Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), ctxt->library[i].file, ctxt->library[i].objref);
   202  		iscgo |= strcmp(ctxt->library[i].pkg, "runtime/cgo") == 0;
   203  		objfile(ctxt->library[i].file, ctxt->library[i].pkg);
   204  	}
   205  	
   206  	if(linkmode == LinkExternal && !iscgo) {
   207  		// This indicates a user requested -linkmode=external.
   208  		// The startup code uses an import of runtime/cgo to decide
   209  		// whether to initialize the TLS.  So give it one.  This could
   210  		// be handled differently but it's an unusual case.
   211  		if(HEADTYPE != Hhaiku)
   212  			loadinternal("runtime/cgo");
   213  
   214  		if(i < ctxt->libraryp)
   215  			objfile(ctxt->library[i].file, ctxt->library[i].pkg);
   216  
   217  		// Pretend that we really imported the package.
   218  		s = linklookup(ctxt, "go.importpath.runtime/cgo.", 0);
   219  		s->type = SDATA;
   220  		s->dupok = 1;
   221  		s->reachable = 1;
   222  
   223  		// Provided by the code that imports the package.
   224  		// Since we are simulating the import, we have to provide this string.
   225  		cgostrsym = "go.string.\"runtime/cgo\"";
   226  		if(linkrlookup(ctxt, cgostrsym, 0) == nil) {
   227  			s = linklookup(ctxt, cgostrsym, 0);
   228  			s->type = SRODATA;
   229  			s->reachable = 1;
   230  			addstrdata(cgostrsym, "runtime/cgo");
   231  		}
   232  	}
   233  
   234  	if(linkmode == LinkAuto) {
   235  		if(iscgo && externalobj)
   236  			linkmode = LinkExternal;
   237  		else
   238  			linkmode = LinkInternal;
   239  
   240  		// Force external linking for android.
   241  		if(strcmp(goos, "android") == 0)
   242  			linkmode = LinkExternal;
   243  	}
   244  
   245  	if(linkmode == LinkInternal) {
   246  		// Drop all the cgo_import_static declarations.
   247  		// Turns out we won't be needing them.
   248  		for(s = ctxt->allsym; s != S; s = s->allsym)
   249  			if(s->type == SHOSTOBJ) {
   250  				// If a symbol was marked both
   251  				// cgo_import_static and cgo_import_dynamic,
   252  				// then we want to make it cgo_import_dynamic
   253  				// now.
   254  				if(s->extname != nil && s->dynimplib != nil && s->cgoexport == 0) {
   255  					s->type = SDYNIMPORT;
   256  				} else
   257  					s->type = 0;
   258  			}
   259  	}
   260  	
   261  	tlsg = linklookup(ctxt, "runtime.tlsg", 0);
   262  	tlsg->type = STLSBSS;
   263  	tlsg->size = PtrSize;
   264  	tlsg->hide = 1;
   265  	tlsg->reachable = 1;
   266  	ctxt->tlsg = tlsg;
   267  
   268  	// Now that we know the link mode, trim the dynexp list.
   269  	x = CgoExportDynamic;
   270  	if(linkmode == LinkExternal)
   271  		x = CgoExportStatic;
   272  	w = 0;
   273  	for(i=0; i<ndynexp; i++)
   274  		if(dynexp[i]->cgoexport & x)
   275  			dynexp[w++] = dynexp[i];
   276  	ndynexp = w;
   277  	
   278  	// In internal link mode, read the host object files.
   279  	if(linkmode == LinkInternal)
   280  		hostobjs();
   281  	else
   282  		hostlinksetup();
   283  
   284  	// We've loaded all the code now.
   285  	// If there are no dynamic libraries needed, gcc disables dynamic linking.
   286  	// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   287  	// assumes that a dynamic binary always refers to at least one dynamic library.
   288  	// Rather than be a source of test cases for glibc, disable dynamic linking
   289  	// the same way that gcc would.
   290  	//
   291  	// Exception: on OS X, programs such as Shark only work with dynamic
   292  	// binaries, so leave it enabled on OS X (Mach-O) binaries.
   293  	// Also leave it enabled on Solaris which doesn't support
   294  	// statically linked binaries.
   295  	if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin && HEADTYPE != Hsolaris && HEADTYPE != Hhaiku)
   296  		debug['d'] = 1;
   297  	
   298  	importcycles();
   299  }
   300  
   301  /*
   302   * look for the next file in an archive.
   303   * adapted from libmach.
   304   */
   305  static vlong
   306  nextar(Biobuf *bp, vlong off, struct ar_hdr *a)
   307  {
   308  	int r;
   309  	int32 arsize;
   310  	char *buf;
   311  
   312  	if (off&01)
   313  		off++;
   314  	Bseek(bp, off, 0);
   315  	buf = Brdline(bp, '\n');
   316  	r = Blinelen(bp);
   317  	if(buf == nil) {
   318  		if(r == 0)
   319  			return 0;
   320  		return -1;
   321  	}
   322  	if(r != SAR_HDR)
   323  		return -1;
   324  	memmove(a, buf, SAR_HDR);
   325  	if(strncmp(a->fmag, ARFMAG, sizeof a->fmag))
   326  		return -1;
   327  	arsize = strtol(a->size, 0, 0);
   328  	if (arsize&1)
   329  		arsize++;
   330  	return arsize + r;
   331  }
   332  
   333  void
   334  objfile(char *file, char *pkg)
   335  {
   336  	vlong off, l;
   337  	Biobuf *f;
   338  	char magbuf[SARMAG];
   339  	char pname[150];
   340  	struct ar_hdr arhdr;
   341  
   342  	pkg = smprint("%i", pkg);
   343  
   344  	if(debug['v'] > 1)
   345  		Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
   346  	Bflush(&bso);
   347  	f = Bopen(file, 0);
   348  	if(f == nil) {
   349  		diag("cannot open file: %s", file);
   350  		errorexit();
   351  	}
   352  	l = Bread(f, magbuf, SARMAG);
   353  	if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
   354  		/* load it as a regular file */
   355  		l = Bseek(f, 0L, 2);
   356  		Bseek(f, 0L, 0);
   357  		ldobj(f, pkg, l, file, file, FileObj);
   358  		Bterm(f);
   359  		free(pkg);
   360  		return;
   361  	}
   362  	
   363  	/* skip over optional __.GOSYMDEF and process __.PKGDEF */
   364  	off = Boffset(f);
   365  	l = nextar(f, off, &arhdr);
   366  	if(l <= 0) {
   367  		diag("%s: short read on archive file symbol header", file);
   368  		goto out;
   369  	}
   370  	if(strncmp(arhdr.name, symname, strlen(symname)) == 0) {
   371  		off += l;
   372  		l = nextar(f, off, &arhdr);
   373  		if(l <= 0) {
   374  			diag("%s: short read on archive file symbol header", file);
   375  			goto out;
   376  		}
   377  	}
   378  
   379  	if(strncmp(arhdr.name, pkgname, strlen(pkgname))) {
   380  		diag("%s: cannot find package header", file);
   381  		goto out;
   382  	}
   383  	off += l;
   384  
   385  	if(debug['u'])
   386  		ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef);
   387  
   388  	/*
   389  	 * load all the object files from the archive now.
   390  	 * this gives us sequential file access and keeps us
   391  	 * from needing to come back later to pick up more
   392  	 * objects.  it breaks the usual C archive model, but
   393  	 * this is Go, not C.  the common case in Go is that
   394  	 * we need to load all the objects, and then we throw away
   395  	 * the individual symbols that are unused.
   396  	 *
   397  	 * loading every object will also make it possible to
   398  	 * load foreign objects not referenced by __.GOSYMDEF.
   399  	 */
   400  	for(;;) {
   401  		l = nextar(f, off, &arhdr);
   402  		if(l == 0)
   403  			break;
   404  		if(l < 0) {
   405  			diag("%s: malformed archive", file);
   406  			goto out;
   407  		}
   408  		off += l;
   409  
   410  		l = SARNAME;
   411  		while(l > 0 && arhdr.name[l-1] == ' ')
   412  			l--;
   413  		snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name);
   414  		l = atolwhex(arhdr.size);
   415  		ldobj(f, pkg, l, pname, file, ArchiveObj);
   416  	}
   417  
   418  out:
   419  	Bterm(f);
   420  	free(pkg);
   421  }
   422  
   423  static void
   424  dowrite(int fd, char *p, int n)
   425  {
   426  	int m;
   427  	
   428  	while(n > 0) {
   429  		m = write(fd, p, n);
   430  		if(m <= 0) {
   431  			ctxt->cursym = S;
   432  			diag("write error: %r");
   433  			errorexit();
   434  		}
   435  		n -= m;
   436  		p += m;
   437  	}
   438  }
   439  
   440  typedef struct Hostobj Hostobj;
   441  
   442  struct Hostobj
   443  {
   444  	void (*ld)(Biobuf*, char*, int64, char*);
   445  	char *pkg;
   446  	char *pn;
   447  	char *file;
   448  	int64 off;
   449  	int64 len;
   450  };
   451  
   452  Hostobj *hostobj;
   453  int nhostobj;
   454  int mhostobj;
   455  
   456  // These packages can use internal linking mode.
   457  // Others trigger external mode.
   458  const char *internalpkg[] = {
   459  	"crypto/x509",
   460  	"net",
   461  	"os/user",
   462  	"runtime/cgo",
   463  	"runtime/race"
   464  };
   465  
   466  void
   467  ldhostobj(void (*ld)(Biobuf*, char*, int64, char*), Biobuf *f, char *pkg, int64 len, char *pn, char *file)
   468  {
   469  	int i, isinternal;
   470  	Hostobj *h;
   471  
   472  	isinternal = 0;
   473  	for(i=0; i<nelem(internalpkg); i++) {
   474  		if(strcmp(pkg, internalpkg[i]) == 0) {
   475  			isinternal = 1;
   476  			break;
   477  		}
   478  	}
   479  
   480  	// DragonFly declares errno with __thread, which results in a symbol
   481  	// type of R_386_TLS_GD or R_X86_64_TLSGD. The Go linker does not
   482  	// currently know how to handle TLS relocations, hence we have to
   483  	// force external linking for any libraries that link in code that
   484  	// uses errno. This can be removed if the Go linker ever supports
   485  	// these relocation types.
   486  	if(HEADTYPE == Hdragonfly)
   487  	if(strcmp(pkg, "net") == 0 || strcmp(pkg, "os/user") == 0)
   488  		isinternal = 0;
   489  
   490  	if(!isinternal)
   491  		externalobj = 1;
   492  
   493  	if(nhostobj >= mhostobj) {
   494  		if(mhostobj == 0)
   495  			mhostobj = 16;
   496  		else
   497  			mhostobj *= 2;
   498  		hostobj = erealloc(hostobj, mhostobj*sizeof hostobj[0]);
   499  	}
   500  	h = &hostobj[nhostobj++];
   501  	h->ld = ld;
   502  	h->pkg = estrdup(pkg);
   503  	h->pn = estrdup(pn);
   504  	h->file = estrdup(file);
   505  	h->off = Boffset(f);
   506  	h->len = len;
   507  }
   508  
   509  void
   510  hostobjs(void)
   511  {
   512  	int i;
   513  	Biobuf *f;
   514  	Hostobj *h;
   515  	
   516  	for(i=0; i<nhostobj; i++) {
   517  		h = &hostobj[i];
   518  		f = Bopen(h->file, OREAD);
   519  		if(f == nil) {
   520  			ctxt->cursym = S;
   521  			diag("cannot reopen %s: %r", h->pn);
   522  			errorexit();
   523  		}
   524  		Bseek(f, h->off, 0);
   525  		h->ld(f, h->pkg, h->len, h->pn);
   526  		Bterm(f);
   527  	}
   528  }
   529  
   530  // provided by lib9
   531  int runcmd(char**);
   532  char* mktempdir(void);
   533  void removeall(char*);
   534  
   535  static void
   536  rmtemp(void)
   537  {
   538  	removeall(tmpdir);
   539  }
   540  
   541  static void
   542  hostlinksetup(void)
   543  {
   544  	char *p;
   545  
   546  	if(linkmode != LinkExternal)
   547  		return;
   548  
   549  	// create temporary directory and arrange cleanup
   550  	if(tmpdir == nil) {
   551  		tmpdir = mktempdir();
   552  		atexit(rmtemp);
   553  	}
   554  
   555  	// change our output to temporary object file
   556  	close(cout);
   557  	p = smprint("%s/go.o", tmpdir);
   558  	cout = create(p, 1, 0775);
   559  	if(cout < 0) {
   560  		diag("cannot create %s: %r", p);
   561  		errorexit();
   562  	}
   563  	free(p);
   564  }
   565  
   566  void
   567  hostlink(void)
   568  {
   569  	char *p, **argv;
   570  	int c, i, w, n, argc, len;
   571  	Hostobj *h;
   572  	Biobuf *f;
   573  	static char buf[64<<10];
   574  
   575  	if(linkmode != LinkExternal || nerrors > 0)
   576  		return;
   577  
   578  	c = 0;
   579  	p = extldflags;
   580  	while(p != nil) {
   581  		while(*p == ' ')
   582  			p++;
   583  		if(*p == '\0')
   584  			break;
   585  		c++;
   586  		p = strchr(p + 1, ' ');
   587  	}
   588  
   589  	argv = malloc((14+nhostobj+nldflag+c)*sizeof argv[0]);
   590  	argc = 0;
   591  	if(extld == nil)
   592  		extld = "gcc";
   593  	argv[argc++] = extld;
   594  	switch(thechar){
   595  	case '8':
   596  		argv[argc++] = "-m32";
   597  		break;
   598  	case '6':
   599  		argv[argc++] = "-m64";
   600  		break;
   601  	case '5':
   602  		argv[argc++] = "-marm";
   603  		break;
   604  	}
   605  	if(!debug['s'] && !debug_s) {
   606  		argv[argc++] = "-gdwarf-2"; 
   607  	} else {
   608  		argv[argc++] = "-s";
   609  	}
   610  	if(HEADTYPE == Hdarwin)
   611  		argv[argc++] = "-Wl,-no_pie,-pagezero_size,4000000";
   612  	if(HEADTYPE == Hopenbsd)
   613  		argv[argc++] = "-Wl,-nopie";
   614  
   615  	if(HEADTYPE == Hhaiku)
   616  		argv[argc++] = "-fPIC";
   617  	
   618  	if(iself && AssumeGoldLinker)
   619  		argv[argc++] = "-Wl,--rosegment";
   620  
   621  	if(flag_shared) {
   622  		argv[argc++] = "-Wl,-Bsymbolic";
   623  		argv[argc++] = "-shared";
   624  	}
   625  	argv[argc++] = "-o";
   626  	argv[argc++] = outfile;
   627  	
   628  	if(rpath)
   629  		argv[argc++] = smprint("-Wl,-rpath,%s", rpath);
   630  	
   631  	if(iself && HEADTYPE != Hhaiku)
   632  		argv[argc++] = "-rdynamic";
   633  
   634  	// Force global symbols to be exported for dlopen, etc.
   635  	if(iself)
   636  		// argv[argc++] = "-rdynamic";
   637  
   638  	if(strstr(argv[0], "clang") != nil)
   639  		argv[argc++] = "-Qunused-arguments";
   640  
   641  	// already wrote main object file
   642  	// copy host objects to temporary directory
   643  	for(i=0; i<nhostobj; i++) {
   644  		h = &hostobj[i];
   645  		f = Bopen(h->file, OREAD);
   646  		if(f == nil) {
   647  			ctxt->cursym = S;
   648  			diag("cannot reopen %s: %r", h->pn);
   649  			errorexit();
   650  		}
   651  		Bseek(f, h->off, 0);
   652  		p = smprint("%s/%06d.o", tmpdir, i);
   653  		argv[argc++] = p;
   654  		w = create(p, 1, 0775);
   655  		if(w < 0) {
   656  			ctxt->cursym = S;
   657  			diag("cannot create %s: %r", p);
   658  			errorexit();
   659  		}
   660  		len = h->len;
   661  		while(len > 0 && (n = Bread(f, buf, sizeof buf)) > 0){
   662  			if(n > len)
   663  				n = len;
   664  			dowrite(w, buf, n);
   665  			len -= n;
   666  		}
   667  		if(close(w) < 0) {
   668  			ctxt->cursym = S;
   669  			diag("cannot write %s: %r", p);
   670  			errorexit();
   671  		}
   672  		Bterm(f);
   673  	}
   674  	
   675  	argv[argc++] = smprint("%s/go.o", tmpdir);
   676  	for(i=0; i<nldflag; i++)
   677  		argv[argc++] = ldflag[i];
   678  
   679  	p = extldflags;
   680  	while(p != nil) {
   681  		while(*p == ' ')
   682  			*p++ = '\0';
   683  		if(*p == '\0')
   684  			break;
   685  		argv[argc++] = p;
   686  
   687  		// clang, unlike GCC, passes -rdynamic to the linker
   688  		// even when linking with -static, causing a linker
   689  		// error when using GNU ld.  So take out -rdynamic if
   690  		// we added it.  We do it in this order, rather than
   691  		// only adding -rdynamic later, so that -extldflags
   692  		// can override -rdynamic without using -static.
   693  		if(iself && strncmp(p, "-static", 7) == 0 && (p[7]==' ' || p[7]=='\0')) {
   694  			for(i=0; i<argc; i++) {
   695  				if(strcmp(argv[i], "-rdynamic") == 0)
   696  					argv[i] = "-static";
   697  			}
   698  		}
   699  
   700  		p = strchr(p + 1, ' ');
   701  	}
   702  
   703  	argv[argc] = nil;
   704  
   705  	quotefmtinstall();
   706  	if(debug['v']) {
   707  		Bprint(&bso, "host link:");
   708  		for(i=0; i<argc; i++)
   709  			Bprint(&bso, " %q", argv[i]);
   710  		Bprint(&bso, "\n");
   711  		Bflush(&bso);
   712  	}
   713  
   714  	if(runcmd(argv) < 0) {
   715  		ctxt->cursym = S;
   716  		diag("%s: running %s failed: %r", argv0, argv[0]);
   717  		errorexit();
   718  	}
   719  }
   720  
   721  void
   722  ldobj(Biobuf *f, char *pkg, int64 len, char *pn, char *file, int whence)
   723  {
   724  	char *line;
   725  	int n, c1, c2, c3, c4;
   726  	uint32 magic;
   727  	vlong import0, import1, eof;
   728  	char *t;
   729  
   730  	eof = Boffset(f) + len;
   731  
   732  	pn = estrdup(pn);
   733  
   734  	c1 = BGETC(f);
   735  	c2 = BGETC(f);
   736  	c3 = BGETC(f);
   737  	c4 = BGETC(f);
   738  	Bungetc(f);
   739  	Bungetc(f);
   740  	Bungetc(f);
   741  	Bungetc(f);
   742  
   743  	magic = c1<<24 | c2<<16 | c3<<8 | c4;
   744  	if(magic == 0x7f454c46) {	// \x7F E L F
   745  		ldhostobj(ldelf, f, pkg, len, pn, file);
   746  		return;
   747  	}
   748  	if((magic&~1) == 0xfeedface || (magic&~0x01000000) == 0xcefaedfe) {
   749  		ldhostobj(ldmacho, f, pkg, len, pn, file);
   750  		return;
   751  	}
   752  	if(c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86) {
   753  		ldhostobj(ldpe, f, pkg, len, pn, file);
   754  		return;
   755  	}
   756  
   757  	/* check the header */
   758  	line = Brdline(f, '\n');
   759  	if(line == nil) {
   760  		if(Blinelen(f) > 0) {
   761  			diag("%s: not an object file", pn);
   762  			return;
   763  		}
   764  		goto eof;
   765  	}
   766  	n = Blinelen(f) - 1;
   767  	line[n] = '\0';
   768  	if(strncmp(line, "go object ", 10) != 0) {
   769  		if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) {
   770  			print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar);
   771  			errorexit();
   772  		}
   773  		if(strcmp(line, thestring) == 0) {
   774  			// old header format: just $GOOS
   775  			diag("%s: stale object file", pn);
   776  			return;
   777  		}
   778  		diag("%s: not an object file", pn);
   779  		free(pn);
   780  		return;
   781  	}
   782  	
   783  	// First, check that the basic goos, goarch, and version match.
   784  	t = smprint("%s %s %s ", goos, getgoarch(), getgoversion());
   785  	line[n] = ' ';
   786  	if(strncmp(line+10, t, strlen(t)) != 0 && !debug['f']) {
   787  		line[n] = '\0';
   788  		diag("%s: object is [%s] expected [%s]", pn, line+10, t);
   789  		free(t);
   790  		free(pn);
   791  		return;
   792  	}
   793  	
   794  	// Second, check that longer lines match each other exactly,
   795  	// so that the Go compiler and write additional information
   796  	// that must be the same from run to run.
   797  	line[n] = '\0';
   798  	if(n-10 > strlen(t)) {
   799  		if(theline == nil)
   800  			theline = estrdup(line+10);
   801  		else if(strcmp(theline, line+10) != 0) {
   802  			line[n] = '\0';
   803  			diag("%s: object is [%s] expected [%s]", pn, line+10, theline);
   804  			free(t);
   805  			free(pn);
   806  			return;
   807  		}
   808  	}
   809  	free(t);
   810  	line[n] = '\n';
   811  
   812  	/* skip over exports and other info -- ends with \n!\n */
   813  	import0 = Boffset(f);
   814  	c1 = '\n';	// the last line ended in \n
   815  	c2 = BGETC(f);
   816  	c3 = BGETC(f);
   817  	while(c1 != '\n' || c2 != '!' || c3 != '\n') {
   818  		c1 = c2;
   819  		c2 = c3;
   820  		c3 = BGETC(f);
   821  		if(c3 == Beof)
   822  			goto eof;
   823  	}
   824  	import1 = Boffset(f);
   825  
   826  	Bseek(f, import0, 0);
   827  	ldpkg(f, pkg, import1 - import0 - 2, pn, whence);	// -2 for !\n
   828  	Bseek(f, import1, 0);
   829  
   830  	ldobjfile(ctxt, f, pkg, eof - Boffset(f), pn);
   831  	free(pn);
   832  	return;
   833  
   834  eof:
   835  	diag("truncated object file: %s", pn);
   836  	free(pn);
   837  }
   838  
   839  void
   840  zerosig(char *sp)
   841  {
   842  	LSym *s;
   843  
   844  	s = linklookup(ctxt, sp, 0);
   845  	s->sig = 0;
   846  }
   847  
   848  void
   849  mywhatsys(void)
   850  {
   851  	goroot = getgoroot();
   852  	goos = getgoos();
   853  	goarch = getgoarch();
   854  
   855  	if(strncmp(goarch, thestring, strlen(thestring)) != 0)
   856  		sysfatal("cannot use %cc with GOARCH=%s", thechar, goarch);
   857  }
   858  
   859  int
   860  pathchar(void)
   861  {
   862  	return '/';
   863  }
   864  
   865  static	uchar*	hunk;
   866  static	uint32	nhunk;
   867  #define	NHUNK	(10UL<<20)
   868  
   869  void*
   870  mal(uint32 n)
   871  {
   872  	void *v;
   873  
   874  	n = (n+7)&~7;
   875  	if(n > NHUNK) {
   876  		v = malloc(n);
   877  		if(v == nil) {
   878  			diag("out of memory");
   879  			errorexit();
   880  		}
   881  		memset(v, 0, n);
   882  		return v;
   883  	}
   884  	if(n > nhunk) {
   885  		hunk = malloc(NHUNK);
   886  		if(hunk == nil) {
   887  			diag("out of memory");
   888  			errorexit();
   889  		}
   890  		nhunk = NHUNK;
   891  	}
   892  
   893  	v = hunk;
   894  	nhunk -= n;
   895  	hunk += n;
   896  
   897  	memset(v, 0, n);
   898  	return v;
   899  }
   900  
   901  void
   902  unmal(void *v, uint32 n)
   903  {
   904  	n = (n+7)&~7;
   905  	if(hunk - n == v) {
   906  		hunk -= n;
   907  		nhunk += n;
   908  	}
   909  }
   910  
   911  // Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
   912  /*
   913   * Convert raw string to the prefix that will be used in the symbol table.
   914   * Invalid bytes turn into %xx.	 Right now the only bytes that need
   915   * escaping are %, ., and ", but we escape all control characters too.
   916   *
   917   * If you edit this, edit ../gc/subr.c:/^pathtoprefix too.
   918   * If you edit this, edit ../../debug/goobj/read.go:/importPathToPrefix too.
   919   */
   920  static char*
   921  pathtoprefix(char *s)
   922  {
   923  	static char hex[] = "0123456789abcdef";
   924  	char *p, *r, *w, *l;
   925  	int n;
   926  
   927  	// find first character past the last slash, if any.
   928  	l = s;
   929  	for(r=s; *r; r++)
   930  		if(*r == '/')
   931  			l = r+1;
   932  
   933  	// check for chars that need escaping
   934  	n = 0;
   935  	for(r=s; *r; r++)
   936  		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f)
   937  			n++;
   938  
   939  	// quick exit
   940  	if(n == 0)
   941  		return s;
   942  
   943  	// escape
   944  	p = mal((r-s)+1+2*n);
   945  	for(r=s, w=p; *r; r++) {
   946  		if(*r <= ' ' || (*r == '.' && r >= l) || *r == '%' || *r == '"' || *r >= 0x7f) {
   947  			*w++ = '%';
   948  			*w++ = hex[(*r>>4)&0xF];
   949  			*w++ = hex[*r&0xF];
   950  		} else
   951  			*w++ = *r;
   952  	}
   953  	*w = '\0';
   954  	return p;
   955  }
   956  
   957  int
   958  iconv(Fmt *fp)
   959  {
   960  	char *p;
   961  
   962  	p = va_arg(fp->args, char*);
   963  	if(p == nil) {
   964  		fmtstrcpy(fp, "<nil>");
   965  		return 0;
   966  	}
   967  	p = pathtoprefix(p);
   968  	fmtstrcpy(fp, p);
   969  	return 0;
   970  }
   971  
   972  Section*
   973  addsection(Segment *seg, char *name, int rwx)
   974  {
   975  	Section **l;
   976  	Section *sect;
   977  	
   978  	for(l=&seg->sect; *l; l=&(*l)->next)
   979  		;
   980  	sect = mal(sizeof *sect);
   981  	sect->rwx = rwx;
   982  	sect->name = name;
   983  	sect->seg = seg;
   984  	sect->align = PtrSize; // everything is at least pointer-aligned
   985  	*l = sect;
   986  	return sect;
   987  }
   988  
   989  uint16
   990  le16(uchar *b)
   991  {
   992  	return b[0] | b[1]<<8;
   993  }
   994  
   995  uint32
   996  le32(uchar *b)
   997  {
   998  	return b[0] | b[1]<<8 | b[2]<<16 | (uint32)b[3]<<24;
   999  }
  1000  
  1001  uint64
  1002  le64(uchar *b)
  1003  {
  1004  	return le32(b) | (uint64)le32(b+4)<<32;
  1005  }
  1006  
  1007  uint16
  1008  be16(uchar *b)
  1009  {
  1010  	return b[0]<<8 | b[1];
  1011  }
  1012  
  1013  uint32
  1014  be32(uchar *b)
  1015  {
  1016  	return (uint32)b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
  1017  }
  1018  
  1019  uint64
  1020  be64(uchar *b)
  1021  {
  1022  	return (uvlong)be32(b)<<32 | be32(b+4);
  1023  }
  1024  
  1025  Endian be = { be16, be32, be64 };
  1026  Endian le = { le16, le32, le64 };
  1027  
  1028  typedef struct Chain Chain;
  1029  struct Chain
  1030  {
  1031  	LSym *sym;
  1032  	Chain *up;
  1033  	int limit;  // limit on entry to sym
  1034  };
  1035  
  1036  static int stkcheck(Chain*, int);
  1037  static void stkprint(Chain*, int);
  1038  static void stkbroke(Chain*, int);
  1039  static LSym *morestack;
  1040  static LSym *newstack;
  1041  
  1042  enum
  1043  {
  1044  	HasLinkRegister = (thechar == '5'),
  1045  };
  1046  
  1047  // TODO: Record enough information in new object files to
  1048  // allow stack checks here.
  1049  
  1050  static int
  1051  callsize(void)
  1052  {
  1053  	if(thechar == '5')
  1054  		return 0;
  1055  	return RegSize;
  1056  }
  1057  
  1058  void
  1059  dostkcheck(void)
  1060  {
  1061  	Chain ch;
  1062  	LSym *s;
  1063  	
  1064  	morestack = linklookup(ctxt, "runtime.morestack", 0);
  1065  	newstack = linklookup(ctxt, "runtime.newstack", 0);
  1066  
  1067  	// Every splitting function ensures that there are at least StackLimit
  1068  	// bytes available below SP when the splitting prologue finishes.
  1069  	// If the splitting function calls F, then F begins execution with
  1070  	// at least StackLimit - callsize() bytes available.
  1071  	// Check that every function behaves correctly with this amount
  1072  	// of stack, following direct calls in order to piece together chains
  1073  	// of non-splitting functions.
  1074  	ch.up = nil;
  1075  	ch.limit = StackLimit - callsize();
  1076  
  1077  	// Check every function, but do the nosplit functions in a first pass,
  1078  	// to make the printed failure chains as short as possible.
  1079  	for(s = ctxt->textp; s != nil; s = s->next) {
  1080  		// runtime.racesymbolizethunk is called from gcc-compiled C
  1081  		// code running on the operating system thread stack.
  1082  		// It uses more than the usual amount of stack but that's okay.
  1083  		if(strcmp(s->name, "runtime.racesymbolizethunk") == 0)
  1084  			continue;
  1085  
  1086  		if(s->nosplit) {
  1087  		ctxt->cursym = s;
  1088  		ch.sym = s;
  1089  		stkcheck(&ch, 0);
  1090  	}
  1091  	}
  1092  	for(s = ctxt->textp; s != nil; s = s->next) {
  1093  		if(!s->nosplit) {
  1094  		ctxt->cursym = s;
  1095  		ch.sym = s;
  1096  		stkcheck(&ch, 0);
  1097  	}
  1098  }
  1099  }
  1100  
  1101  static int
  1102  stkcheck(Chain *up, int depth)
  1103  {
  1104  	Chain ch, ch1;
  1105  	LSym *s;
  1106  	int limit;
  1107  	Reloc *r, *endr;
  1108  	Pciter pcsp;
  1109  	
  1110  	limit = up->limit;
  1111  	s = up->sym;
  1112  	
  1113  	// Don't duplicate work: only need to consider each
  1114  	// function at top of safe zone once.
  1115  	if(limit == StackLimit-callsize()) {
  1116  		if(s->stkcheck)
  1117  		return 0;
  1118  		s->stkcheck = 1;
  1119  	}
  1120  	
  1121  	if(depth > 100) {
  1122  		diag("nosplit stack check too deep");
  1123  		stkbroke(up, 0);
  1124  		return -1;
  1125  	}
  1126  
  1127  	if(s->external || s->pcln == nil) {
  1128  		// external function.
  1129  		// should never be called directly.
  1130  		// only diagnose the direct caller.
  1131  		if(depth == 1 && s->type != SXREF)
  1132  			diag("call to external function %s", s->name);
  1133  		return -1;
  1134  	}
  1135  
  1136  	if(limit < 0) {
  1137  		stkbroke(up, limit);
  1138  		return -1;
  1139  	}
  1140  
  1141  	// morestack looks like it calls functions,
  1142  	// but it switches the stack pointer first.
  1143  	if(s == morestack)
  1144  		return 0;
  1145  
  1146  	ch.up = up;
  1147  	
  1148  	// Walk through sp adjustments in function, consuming relocs.
  1149  	r = s->r;
  1150  	endr = r + s->nr;
  1151  	for(pciterinit(ctxt, &pcsp, &s->pcln->pcsp); !pcsp.done; pciternext(&pcsp)) {
  1152  		// pcsp.value is in effect for [pcsp.pc, pcsp.nextpc).
  1153  
  1154  		// Check stack size in effect for this span.
  1155  		if(limit - pcsp.value < 0) {
  1156  			stkbroke(up, limit - pcsp.value);
  1157  			return -1;
  1158  		}
  1159  
  1160  		// Process calls in this span.
  1161  		for(; r < endr && r->off < pcsp.nextpc; r++) {
  1162  			switch(r->type) {
  1163  			case R_CALL:
  1164  			case R_CALLARM:
  1165  				// Direct call.
  1166  				ch.limit = limit - pcsp.value - callsize();
  1167  				ch.sym = r->sym;
  1168  				if(stkcheck(&ch, depth+1) < 0)
  1169  					return -1;
  1170  
  1171  				// If this is a call to morestack, we've just raised our limit back
  1172  				// to StackLimit beyond the frame size.
  1173  				if(strncmp(r->sym->name, "runtime.morestack", 17) == 0) {
  1174  					limit = StackLimit + s->locals;
  1175  					if(thechar == '5')
  1176  						limit += 4; // saved LR
  1177  				}
  1178  				break;
  1179  
  1180  			case R_CALLIND:
  1181  				// Indirect call.  Assume it is a call to a splitting function,
  1182  				// so we have to make sure it can call morestack.
  1183  				// Arrange the data structures to report both calls, so that
  1184  				// if there is an error, stkprint shows all the steps involved.
  1185  				ch.limit = limit - pcsp.value - callsize();
  1186  				ch.sym = nil;
  1187  				ch1.limit = ch.limit - callsize(); // for morestack in called prologue
  1188  				ch1.up = &ch;
  1189  				ch1.sym = morestack;
  1190  				if(stkcheck(&ch1, depth+2) < 0)
  1191  					return -1;
  1192  				break;
  1193  			}
  1194  		}
  1195  		}
  1196  		
  1197  	return 0;
  1198  }
  1199  
  1200  static void
  1201  stkbroke(Chain *ch, int limit)
  1202  {
  1203  	diag("nosplit stack overflow");
  1204  	stkprint(ch, limit);
  1205  }
  1206  
  1207  static void
  1208  stkprint(Chain *ch, int limit)
  1209  {
  1210  	char *name;
  1211  
  1212  	if(ch->sym)
  1213  		name = ch->sym->name;
  1214  	else
  1215  		name = "function pointer";
  1216  
  1217  	if(ch->up == nil) {
  1218  		// top of chain.  ch->sym != nil.
  1219  		if(ch->sym->nosplit)
  1220  			print("\t%d\tassumed on entry to %s\n", ch->limit, name);
  1221  		else
  1222  			print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
  1223  	} else {
  1224  		stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize);
  1225  		if(!HasLinkRegister)
  1226  			print("\t%d\ton entry to %s\n", ch->limit, name);
  1227  	}
  1228  	if(ch->limit != limit)
  1229  		print("\t%d\tafter %s uses %d\n", limit, name, ch->limit - limit);
  1230  }
  1231  
  1232  int
  1233  Yconv(Fmt *fp)
  1234  {
  1235  	LSym *s;
  1236  	Fmt fmt;
  1237  	int i;
  1238  	char *str;
  1239  
  1240  	s = va_arg(fp->args, LSym*);
  1241  	if (s == S) {
  1242  		fmtprint(fp, "<nil>");
  1243  	} else {
  1244  		fmtstrinit(&fmt);
  1245  		fmtprint(&fmt, "%s @0x%08llx [%lld]", s->name, (vlong)s->value, (vlong)s->size);
  1246  		for (i = 0; i < s->size; i++) {
  1247  			if (!(i%8)) fmtprint(&fmt,  "\n\t0x%04x ", i);
  1248  			fmtprint(&fmt, "%02x ", s->p[i]);
  1249  		}
  1250  		fmtprint(&fmt, "\n");
  1251  		for (i = 0; i < s->nr; i++) {
  1252  			fmtprint(&fmt, "\t0x%04x[%x] %d %s[%llx]\n",
  1253  			      s->r[i].off,
  1254  			      s->r[i].siz,
  1255  			      s->r[i].type,
  1256  			      s->r[i].sym->name,
  1257  			      (vlong)s->r[i].add);
  1258  		}
  1259  		str = fmtstrflush(&fmt);
  1260  		fmtstrcpy(fp, str);
  1261  		free(str);
  1262  	}
  1263  
  1264  	return 0;
  1265  }
  1266  
  1267  vlong coutpos;
  1268  
  1269  void
  1270  cflush(void)
  1271  {
  1272  	int n;
  1273  
  1274  	if(cbpmax < cbp)
  1275  		cbpmax = cbp;
  1276  	n = cbpmax - buf.cbuf;
  1277  	dowrite(cout, buf.cbuf, n);
  1278  	coutpos += n;
  1279  	cbp = buf.cbuf;
  1280  	cbc = sizeof(buf.cbuf);
  1281  	cbpmax = cbp;
  1282  }
  1283  
  1284  vlong
  1285  cpos(void)
  1286  {
  1287  	return coutpos + cbp - buf.cbuf;
  1288  }
  1289  
  1290  void
  1291  cseek(vlong p)
  1292  {
  1293  	vlong start;
  1294  	int delta;
  1295  
  1296  	if(cbpmax < cbp)
  1297  		cbpmax = cbp;
  1298  	start = coutpos;
  1299  	if(start <= p && p <= start+(cbpmax - buf.cbuf)) {
  1300  //print("cseek %lld in [%lld,%lld] (%lld)\n", p, start, start+sizeof(buf.cbuf), cpos());
  1301  		delta = p - (start + cbp - buf.cbuf);
  1302  		cbp += delta;
  1303  		cbc -= delta;
  1304  //print("now at %lld\n", cpos());
  1305  		return;
  1306  	}
  1307  
  1308  	cflush();
  1309  	seek(cout, p, 0);
  1310  	coutpos = p;
  1311  }
  1312  
  1313  void
  1314  cwrite(void *buf, int n)
  1315  {
  1316  	cflush();
  1317  	if(n <= 0)
  1318  		return;
  1319  	dowrite(cout, buf, n);
  1320  	coutpos += n;
  1321  }
  1322  
  1323  void
  1324  usage(void)
  1325  {
  1326  	fprint(2, "usage: %cl [options] main.%c\n", thechar, thechar);
  1327  	flagprint(2);
  1328  	exits("usage");
  1329  }
  1330  
  1331  void
  1332  setheadtype(char *s)
  1333  {
  1334  	int h;
  1335  	
  1336  	h = headtype(s);
  1337  	if(h < 0) {
  1338  		fprint(2, "unknown header type -H %s\n", s);
  1339  		errorexit();
  1340  	}
  1341  	headstring = s;
  1342  	HEADTYPE = headtype(s);
  1343  }
  1344  
  1345  void
  1346  setinterp(char *s)
  1347  {
  1348  	debug['I'] = 1; // denote cmdline interpreter override
  1349  	interpreter = s;
  1350  }
  1351  
  1352  void
  1353  doversion(void)
  1354  {
  1355  	print("%cl version %s\n", thechar, getgoversion());
  1356  	errorexit();
  1357  }
  1358  
  1359  void
  1360  genasmsym(void (*put)(LSym*, char*, int, vlong, vlong, int, LSym*))
  1361  {
  1362  	Auto *a;
  1363  	LSym *s;
  1364  	int32 off;
  1365  
  1366  	// These symbols won't show up in the first loop below because we
  1367  	// skip STEXT symbols. Normal STEXT symbols are emitted by walking textp.
  1368  	s = linklookup(ctxt, "runtime.text", 0);
  1369  	if(s->type == STEXT)
  1370  		put(s, s->name, 'T', s->value, s->size, s->version, 0);
  1371  	s = linklookup(ctxt, "runtime.etext", 0);
  1372  	if(s->type == STEXT)
  1373  		put(s, s->name, 'T', s->value, s->size, s->version, 0);
  1374  
  1375  	for(s=ctxt->allsym; s!=S; s=s->allsym) {
  1376  		if(s->hide || (s->name[0] == '.' && s->version == 0 && strcmp(s->name, ".rathole") != 0))
  1377  			continue;
  1378  		switch(s->type&SMASK) {
  1379  		case SCONST:
  1380  		case SRODATA:
  1381  		case SSYMTAB:
  1382  		case SPCLNTAB:
  1383  		case SDATA:
  1384  		case SNOPTRDATA:
  1385  		case SELFROSECT:
  1386  		case SMACHOGOT:
  1387  		case STYPE:
  1388  		case SSTRING:
  1389  		case SGOSTRING:
  1390  		case SWINDOWS:
  1391  			if(!s->reachable)
  1392  				continue;
  1393  			put(s, s->name, 'D', symaddr(s), s->size, s->version, s->gotype);
  1394  			continue;
  1395  
  1396  		case SBSS:
  1397  		case SNOPTRBSS:
  1398  			if(!s->reachable)
  1399  				continue;
  1400  			if(s->np > 0)
  1401  				diag("%s should not be bss (size=%d type=%d special=%d)", s->name, (int)s->np, s->type, s->special);
  1402  			put(s, s->name, 'B', symaddr(s), s->size, s->version, s->gotype);
  1403  			continue;
  1404  
  1405  		case SFILE:
  1406  			put(nil, s->name, 'f', s->value, 0, s->version, 0);
  1407  			continue;
  1408  		}
  1409  	}
  1410  
  1411  	for(s = ctxt->textp; s != nil; s = s->next) {
  1412  		put(s, s->name, 'T', s->value, s->size, s->version, s->gotype);
  1413  
  1414  		// NOTE(ality): acid can't produce a stack trace without .frame symbols
  1415  		put(nil, ".frame", 'm', s->locals+PtrSize, 0, 0, 0);
  1416  
  1417  		for(a=s->autom; a; a=a->link) {
  1418  			// Emit a or p according to actual offset, even if label is wrong.
  1419  			// This avoids negative offsets, which cannot be encoded.
  1420  			if(a->type != A_AUTO && a->type != A_PARAM)
  1421  				continue;
  1422  			
  1423  			// compute offset relative to FP
  1424  			if(a->type == A_PARAM)
  1425  				off = a->aoffset;
  1426  			else
  1427  				off = a->aoffset - PtrSize;
  1428  			
  1429  			// FP
  1430  			if(off >= 0) {
  1431  				put(nil, a->asym->name, 'p', off, 0, 0, a->gotype);
  1432  				continue;
  1433  			}
  1434  			
  1435  			// SP
  1436  			if(off <= -PtrSize) {
  1437  				put(nil, a->asym->name, 'a', -(off+PtrSize), 0, 0, a->gotype);
  1438  				continue;
  1439  			}
  1440  			
  1441  			// Otherwise, off is addressing the saved program counter.
  1442  			// Something underhanded is going on. Say nothing.
  1443  		}
  1444  	}
  1445  	if(debug['v'] || debug['n'])
  1446  		Bprint(&bso, "%5.2f symsize = %ud\n", cputime(), symsize);
  1447  	Bflush(&bso);
  1448  }
  1449  
  1450  vlong
  1451  symaddr(LSym *s)
  1452  {
  1453  	if(!s->reachable)
  1454  		diag("unreachable symbol in symaddr - %s", s->name);
  1455  	return s->value;
  1456  }
  1457  
  1458  void
  1459  xdefine(char *p, int t, vlong v)
  1460  {
  1461  	LSym *s;
  1462  
  1463  	s = linklookup(ctxt, p, 0);
  1464  	s->type = t;
  1465  	s->value = v;
  1466  	s->reachable = 1;
  1467  	s->special = 1;
  1468  }
  1469  
  1470  vlong
  1471  datoff(vlong addr)
  1472  {
  1473  	if(addr >= segdata.vaddr)
  1474  		return addr - segdata.vaddr + segdata.fileoff;
  1475  	if(addr >= segtext.vaddr)
  1476  		return addr - segtext.vaddr + segtext.fileoff;
  1477  	diag("datoff %#llx", addr);
  1478  	return 0;
  1479  }
  1480  
  1481  vlong
  1482  entryvalue(void)
  1483  {
  1484  	char *a;
  1485  	LSym *s;
  1486  
  1487  	a = INITENTRY;
  1488  	if(*a >= '0' && *a <= '9')
  1489  		return atolwhex(a);
  1490  	s = linklookup(ctxt, a, 0);
  1491  	if(s->type == 0)
  1492  		return INITTEXT;
  1493  	if(s->type != STEXT)
  1494  		diag("entry not text: %s", s->name);
  1495  	return s->value;
  1496  }
  1497  
  1498  static void
  1499  undefsym(LSym *s)
  1500  {
  1501  	int i;
  1502  	Reloc *r;
  1503  
  1504  	ctxt->cursym = s;
  1505  	for(i=0; i<s->nr; i++) {
  1506  		r = &s->r[i];
  1507  		if(r->sym == nil) // happens for some external ARM relocs
  1508  			continue;
  1509  		if(r->sym->type == Sxxx || r->sym->type == SXREF)
  1510  			diag("undefined: %s", r->sym->name);
  1511  		if(!r->sym->reachable)
  1512  			diag("use of unreachable symbol: %s", r->sym->name);
  1513  	}
  1514  }
  1515  
  1516  void
  1517  undef(void)
  1518  {
  1519  	LSym *s;
  1520  	
  1521  	for(s = ctxt->textp; s != nil; s = s->next)
  1522  		undefsym(s);
  1523  	for(s = datap; s != nil; s = s->next)
  1524  		undefsym(s);
  1525  	if(nerrors > 0)
  1526  		errorexit();
  1527  }
  1528  
  1529  void
  1530  callgraph(void)
  1531  {
  1532  	LSym *s;
  1533  	Reloc *r;
  1534  	int i;
  1535  
  1536  	if(!debug['c'])
  1537  		return;
  1538  
  1539  	for(s = ctxt->textp; s != nil; s = s->next) {
  1540  		for(i=0; i<s->nr; i++) {
  1541  			r = &s->r[i];
  1542  			if(r->sym == nil)
  1543  				continue;
  1544  			if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT)
  1545  				Bprint(&bso, "%s calls %s\n", s->name, r->sym->name);
  1546  		}
  1547  	}
  1548  }
  1549  
  1550  void
  1551  diag(char *fmt, ...)
  1552  {
  1553  	char buf[1024], *tn, *sep;
  1554  	va_list arg;
  1555  
  1556  	tn = "";
  1557  	sep = "";
  1558  	if(ctxt->cursym != S) {
  1559  		tn = ctxt->cursym->name;
  1560  		sep = ": ";
  1561  	}
  1562  	va_start(arg, fmt);
  1563  	vseprint(buf, buf+sizeof(buf), fmt, arg);
  1564  	va_end(arg);
  1565  	print("%s%s%s\n", tn, sep, buf);
  1566  
  1567  	nerrors++;
  1568  	if(nerrors > 20) {
  1569  		print("too many errors\n");
  1570  		errorexit();
  1571  	}
  1572  }
  1573  
  1574  void
  1575  checkgo(void)
  1576  {
  1577  	LSym *s;
  1578  	Reloc *r;
  1579  	int i;
  1580  	int changed;
  1581  	
  1582  	if(!debug['C'])
  1583  		return;
  1584  	
  1585  	// TODO(rsc,khr): Eventually we want to get to no Go-called C functions at all,
  1586  	// which would simplify this logic quite a bit.
  1587  
  1588  	// Mark every Go-called C function with cfunc=2, recursively.
  1589  	do {
  1590  		changed = 0;
  1591  		for(s = ctxt->textp; s != nil; s = s->next) {
  1592  			if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
  1593  				for(i=0; i<s->nr; i++) {
  1594  					r = &s->r[i];
  1595  					if(r->sym == nil)
  1596  						continue;
  1597  					if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
  1598  						if(r->sym->cfunc == 1) {
  1599  							changed = 1;
  1600  							r->sym->cfunc = 2;
  1601  						}
  1602  					}
  1603  				}
  1604  			}
  1605  		}
  1606  	}while(changed);
  1607  
  1608  	// Complain about Go-called C functions that can split the stack
  1609  	// (that can be preempted for garbage collection or trigger a stack copy).
  1610  	for(s = ctxt->textp; s != nil; s = s->next) {
  1611  		if(s->cfunc == 0 || (s->cfunc == 2 && s->nosplit)) {
  1612  			for(i=0; i<s->nr; i++) {
  1613  				r = &s->r[i];
  1614  				if(r->sym == nil)
  1615  					continue;
  1616  				if((r->type == R_CALL || r->type == R_CALLARM) && r->sym->type == STEXT) {
  1617  					if(s->cfunc == 0 && r->sym->cfunc == 2 && !r->sym->nosplit)
  1618  						print("Go %s calls C %s\n", s->name, r->sym->name);
  1619  					else if(s->cfunc == 2 && s->nosplit && !r->sym->nosplit)
  1620  						print("Go calls C %s calls %s\n", s->name, r->sym->name);
  1621  				}
  1622  			}
  1623  		}
  1624  	}
  1625  }