...
Run Format

Text file src/cmd/ld/lib.c

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

View as plain text