The Go Programming Language

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	"../../pkg/runtime/stack.h"
    35	
    36	#include	<ar.h>
    37	
    38	int iconv(Fmt*);
    39	
    40	char	symname[]	= SYMDEF;
    41	char	pkgname[]	= "__.PKGDEF";
    42	char*	libdir[16];
    43	int	nlibdir = 0;
    44	static int	cout = -1;
    45	
    46	char*	goroot;
    47	char*	goarch;
    48	char*	goos;
    49	
    50	void
    51	Lflag(char *arg)
    52	{
    53		if(nlibdir >= nelem(libdir)-1) {
    54			print("too many -L's: %d\n", nlibdir);
    55			usage();
    56		}
    57		libdir[nlibdir++] = arg;
    58	}
    59	
    60	void
    61	libinit(void)
    62	{
    63		fmtinstall('i', iconv);
    64		fmtinstall('Y', Yconv);
    65		fmtinstall('Z', Zconv);
    66		mywhatsys();	// get goroot, goarch, goos
    67		if(strcmp(goarch, thestring) != 0)
    68			print("goarch is not known: %s\n", goarch);
    69	
    70		// add goroot to the end of the libdir list.
    71		libdir[nlibdir++] = smprint("%s/pkg/%s_%s", goroot, goos, goarch);
    72	
    73		remove(outfile);
    74		cout = create(outfile, 1, 0775);
    75		if(cout < 0) {
    76			diag("cannot create %s", outfile);
    77			errorexit();
    78		}
    79	
    80		if(INITENTRY == nil) {
    81			INITENTRY = mal(strlen(goarch)+strlen(goos)+10);
    82			sprint(INITENTRY, "_rt0_%s_%s", goarch, goos);
    83		}
    84		lookup(INITENTRY, 0)->type = SXREF;
    85	}
    86	
    87	void
    88	errorexit(void)
    89	{
    90		if(nerrors) {
    91			if(cout >= 0)
    92				remove(outfile);
    93			exits("error");
    94		}
    95		exits(0);
    96	}
    97	
    98	void
    99	addlib(char *src, char *obj)
   100	{
   101		char name[1024], pname[1024], comp[256], *p;
   102		int i, search;
   103	
   104		if(histfrogp <= 0)
   105			return;
   106	
   107		search = 0;
   108		if(histfrog[0]->name[1] == '/') {
   109			sprint(name, "");
   110			i = 1;
   111		} else
   112		if(isalpha(histfrog[0]->name[1]) && histfrog[0]->name[2] == ':') {
   113			strcpy(name, histfrog[0]->name+1);
   114			i = 1;
   115		} else
   116		if(histfrog[0]->name[1] == '.') {
   117			sprint(name, ".");
   118			i = 0;
   119		} else {
   120			sprint(name, "");
   121			i = 0;
   122			search = 1;
   123		}
   124	
   125		for(; i<histfrogp; i++) {
   126			snprint(comp, sizeof comp, "%s", histfrog[i]->name+1);
   127			for(;;) {
   128				p = strstr(comp, "$O");
   129				if(p == 0)
   130					break;
   131				memmove(p+1, p+2, strlen(p+2)+1);
   132				p[0] = thechar;
   133			}
   134			for(;;) {
   135				p = strstr(comp, "$M");
   136				if(p == 0)
   137					break;
   138				if(strlen(comp)+strlen(thestring)-2+1 >= sizeof comp) {
   139					diag("library component too long");
   140					return;
   141				}
   142				memmove(p+strlen(thestring), p+2, strlen(p+2)+1);
   143				memmove(p, thestring, strlen(thestring));
   144			}
   145			if(strlen(name) + strlen(comp) + 3 >= sizeof(name)) {
   146				diag("library component too long");
   147				return;
   148			}
   149			if(i > 0 || !search)
   150				strcat(name, "/");
   151			strcat(name, comp);
   152		}
   153		cleanname(name);
   154		
   155		// runtime.a -> runtime
   156		p = nil;
   157		if(strlen(name) > 2 && name[strlen(name)-2] == '.') {
   158			p = name+strlen(name)-2;
   159			*p = '\0';
   160		}
   161		
   162		// already loaded?
   163		for(i=0; i<libraryp; i++)
   164			if(strcmp(library[i].pkg, name) == 0)
   165				return;
   166		
   167		// runtime -> runtime.a for search
   168		if(p != nil)
   169			*p = '.';
   170	
   171		if(search) {
   172			// try dot, -L "libdir", and then goroot.
   173			for(i=0; i<nlibdir; i++) {
   174				snprint(pname, sizeof pname, "%s/%s", libdir[i], name);
   175				if(access(pname, AEXIST) >= 0)
   176					break;
   177			}
   178		}else
   179			strcpy(pname, name);
   180		cleanname(pname);
   181	
   182		/* runtime.a -> runtime */
   183		if(p != nil)
   184			*p = '\0';
   185	
   186		if(debug['v'])
   187			Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
   188	
   189		addlibpath(src, obj, pname, name);
   190	}
   191	
   192	/*
   193	 * add library to library list.
   194	 *	srcref: src file referring to package
   195	 *	objref: object file referring to package
   196	 *	file: object file, e.g., /home/rsc/go/pkg/container/vector.a
   197	 *	pkg: package import path, e.g. container/vector
   198	 */
   199	void
   200	addlibpath(char *srcref, char *objref, char *file, char *pkg)
   201	{
   202		int i;
   203		Library *l;
   204		char *p;
   205	
   206		for(i=0; i<libraryp; i++)
   207			if(strcmp(file, library[i].file) == 0)
   208				return;
   209	
   210		if(debug['v'] > 1)
   211			Bprint(&bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n",
   212				cputime(), srcref, objref, file, pkg);
   213	
   214		if(libraryp == nlibrary){
   215			nlibrary = 50 + 2*libraryp;
   216			library = realloc(library, sizeof library[0] * nlibrary);
   217		}
   218	
   219		l = &library[libraryp++];
   220	
   221		p = mal(strlen(objref) + 1);
   222		strcpy(p, objref);
   223		l->objref = p;
   224	
   225		p = mal(strlen(srcref) + 1);
   226		strcpy(p, srcref);
   227		l->srcref = p;
   228	
   229		p = mal(strlen(file) + 1);
   230		strcpy(p, file);
   231		l->file = p;
   232	
   233		p = mal(strlen(pkg) + 1);
   234		strcpy(p, pkg);
   235		l->pkg = p;
   236	}
   237	
   238	void
   239	loadinternal(char *name)
   240	{
   241		char pname[1024];
   242		int i, found;
   243	
   244		found = 0;
   245		for(i=0; i<nlibdir; i++) {
   246			snprint(pname, sizeof pname, "%s/%s.a", libdir[i], name);
   247			if(debug['v'])
   248				Bprint(&bso, "searching for %s.a in %s\n", name, pname);
   249			if(access(pname, AEXIST) >= 0) {
   250				addlibpath("internal", "internal", pname, name);
   251				found = 1;
   252				break;
   253			}
   254		}
   255		if(!found)
   256			Bprint(&bso, "warning: unable to find %s.a\n", name);
   257	}
   258	
   259	void
   260	loadlib(void)
   261	{
   262		int i;
   263	
   264		loadinternal("runtime");
   265		if(thechar == '5')
   266			loadinternal("math");
   267	
   268		for(i=0; i<libraryp; i++) {
   269			if(debug['v'])
   270				Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
   271			objfile(library[i].file, library[i].pkg);
   272		}
   273		
   274		// We've loaded all the code now.
   275		// If there are no dynamic libraries needed, gcc disables dynamic linking.
   276		// Because of this, glibc's dynamic ELF loader occasionally (like in version 2.13)
   277		// assumes that a dynamic binary always refers to at least one dynamic library.
   278		// Rather than be a source of test cases for glibc, disable dynamic linking
   279		// the same way that gcc would.
   280		//
   281		// Exception: on OS X, programs such as Shark only work with dynamic
   282		// binaries, so leave it enabled on OS X (Mach-O) binaries.
   283		if(!havedynamic && HEADTYPE != Hdarwin)
   284			debug['d'] = 1;
   285		
   286		importcycles();
   287	}
   288	
   289	/*
   290	 * look for the next file in an archive.
   291	 * adapted from libmach.
   292	 */
   293	int
   294	nextar(Biobuf *bp, int off, struct ar_hdr *a)
   295	{
   296		int r;
   297		int32 arsize;
   298	
   299		if (off&01)
   300			off++;
   301		Bseek(bp, off, 0);
   302		r = Bread(bp, a, SAR_HDR);
   303		if(r != SAR_HDR)
   304			return 0;
   305		if(strncmp(a->fmag, ARFMAG, sizeof(a->fmag)))
   306			return -1;
   307		arsize = strtol(a->size, 0, 0);
   308		if (arsize&1)
   309			arsize++;
   310		return arsize + SAR_HDR;
   311	}
   312	
   313	void
   314	objfile(char *file, char *pkg)
   315	{
   316		int32 off, l;
   317		Biobuf *f;
   318		char magbuf[SARMAG];
   319		char pname[150];
   320		struct ar_hdr arhdr;
   321	
   322		pkg = smprint("%i", pkg);
   323	
   324		if(debug['v'])
   325			Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
   326		Bflush(&bso);
   327		f = Bopen(file, 0);
   328		if(f == nil) {
   329			diag("cannot open file: %s", file);
   330			errorexit();
   331		}
   332		l = Bread(f, magbuf, SARMAG);
   333		if(l != SARMAG || strncmp(magbuf, ARMAG, SARMAG)){
   334			/* load it as a regular file */
   335			l = Bseek(f, 0L, 2);
   336			Bseek(f, 0L, 0);
   337			ldobj(f, pkg, l, file, FileObj);
   338			Bterm(f);
   339			return;
   340		}
   341		
   342		/* skip over __.SYMDEF */
   343		off = Boffset(f);
   344		if((l = nextar(f, off, &arhdr)) <= 0) {
   345			diag("%s: short read on archive file symbol header", file);
   346			goto out;
   347		}
   348		if(strncmp(arhdr.name, symname, strlen(symname))) {
   349			diag("%s: first entry not symbol header", file);
   350			goto out;
   351		}
   352		off += l;
   353		
   354		/* skip over (or process) __.PKGDEF */
   355		if((l = nextar(f, off, &arhdr)) <= 0) {
   356			diag("%s: short read on archive file symbol header", file);
   357			goto out;
   358		}
   359		if(strncmp(arhdr.name, pkgname, strlen(pkgname))) {
   360			diag("%s: second entry not package header", file);
   361			goto out;
   362		}
   363		off += l;
   364	
   365		if(debug['u'])
   366			ldpkg(f, pkg, atolwhex(arhdr.size), file, Pkgdef);
   367	
   368		/*
   369		 * load all the object files from the archive now.
   370		 * this gives us sequential file access and keeps us
   371		 * from needing to come back later to pick up more
   372		 * objects.  it breaks the usual C archive model, but
   373		 * this is Go, not C.  the common case in Go is that
   374		 * we need to load all the objects, and then we throw away
   375		 * the individual symbols that are unused.
   376		 *
   377		 * loading every object will also make it possible to
   378		 * load foreign objects not referenced by __.SYMDEF.
   379		 */
   380		for(;;) {
   381			l = nextar(f, off, &arhdr);
   382			if(l == 0)
   383				break;
   384			if(l < 0) {
   385				diag("%s: malformed archive", file);
   386				goto out;
   387			}
   388			off += l;
   389	
   390			l = SARNAME;
   391			while(l > 0 && arhdr.name[l-1] == ' ')
   392				l--;
   393			snprint(pname, sizeof pname, "%s(%.*s)", file, utfnlen(arhdr.name, l), arhdr.name);
   394			l = atolwhex(arhdr.size);
   395			ldobj(f, pkg, l, pname, ArchiveObj);
   396		}
   397	
   398	out:
   399		Bterm(f);
   400	}
   401	
   402	void
   403	ldobj(Biobuf *f, char *pkg, int64 len, char *pn, int whence)
   404	{
   405		char *line;
   406		int n, c1, c2, c3, c4;
   407		uint32 magic;
   408		vlong import0, import1, eof;
   409		char *t;
   410	
   411		eof = Boffset(f) + len;
   412	
   413		pn = strdup(pn);
   414	
   415		c1 = Bgetc(f);
   416		c2 = Bgetc(f);
   417		c3 = Bgetc(f);
   418		c4 = Bgetc(f);
   419		Bungetc(f);
   420		Bungetc(f);
   421		Bungetc(f);
   422		Bungetc(f);
   423	
   424		magic = c1<<24 | c2<<16 | c3<<8 | c4;
   425		if(magic == 0x7f454c46) {	// \x7F E L F
   426			ldelf(f, pkg, len, pn);
   427			return;
   428		}
   429		if((magic&~1) == 0xfeedface || (magic&~0x01000000) == 0xcefaedfe) {
   430			ldmacho(f, pkg, len, pn);
   431			return;
   432		}
   433		if(c1 == 0x4c && c2 == 0x01 || c1 == 0x64 && c2 == 0x86) {
   434			ldpe(f, pkg, len, pn);
   435			return;
   436		}
   437	
   438		/* check the header */
   439		line = Brdline(f, '\n');
   440		if(line == nil) {
   441			if(Blinelen(f) > 0) {
   442				diag("%s: not an object file", pn);
   443				return;
   444			}
   445			goto eof;
   446		}
   447		n = Blinelen(f) - 1;
   448		line[n] = '\0';
   449		if(strncmp(line, "go object ", 10) != 0) {
   450			if(strlen(pn) > 3 && strcmp(pn+strlen(pn)-3, ".go") == 0) {
   451				print("%cl: input %s is not .%c file (use %cg to compile .go files)\n", thechar, pn, thechar, thechar);
   452				errorexit();
   453			}
   454			if(strcmp(line, thestring) == 0) {
   455				// old header format: just $GOOS
   456				diag("%s: stale object file", pn);
   457				return;
   458			}
   459			diag("%s: not an object file", pn);
   460			return;
   461		}
   462		t = smprint("%s %s %s", getgoos(), thestring, getgoversion());
   463		if(strcmp(line+10, t) != 0 && !debug['f']) {
   464			diag("%s: object is [%s] expected [%s]", pn, line+10, t);
   465			free(t);
   466			return;
   467		}
   468		free(t);
   469		line[n] = '\n';
   470	
   471		/* skip over exports and other info -- ends with \n!\n */
   472		import0 = Boffset(f);
   473		c1 = '\n';	// the last line ended in \n
   474		c2 = Bgetc(f);
   475		c3 = Bgetc(f);
   476		while(c1 != '\n' || c2 != '!' || c3 != '\n') {
   477			c1 = c2;
   478			c2 = c3;
   479			c3 = Bgetc(f);
   480			if(c3 == Beof)
   481				goto eof;
   482		}
   483		import1 = Boffset(f);
   484	
   485		Bseek(f, import0, 0);
   486		ldpkg(f, pkg, import1 - import0 - 2, pn, whence);	// -2 for !\n
   487		Bseek(f, import1, 0);
   488	
   489		ldobj1(f, pkg, eof - Boffset(f), pn);
   490		return;
   491	
   492	eof:
   493		diag("truncated object file: %s", pn);
   494	}
   495	
   496	static Sym*
   497	_lookup(char *symb, int v, int creat)
   498	{
   499		Sym *s;
   500		char *p;
   501		int32 h;
   502		int l, c;
   503	
   504		h = v;
   505		for(p=symb; c = *p; p++)
   506			h = h+h+h + c;
   507		l = (p - symb) + 1;
   508		// not if(h < 0) h = ~h, because gcc 4.3 -O2 miscompiles it.
   509		h &= 0xffffff;
   510		h %= NHASH;
   511		for(s = hash[h]; s != S; s = s->hash)
   512			if(memcmp(s->name, symb, l) == 0)
   513				return s;
   514		if(!creat)
   515			return nil;
   516	
   517		s = mal(sizeof(*s));
   518		if(debug['v'] > 1)
   519			Bprint(&bso, "lookup %s\n", symb);
   520	
   521		s->dynid = -1;
   522		s->plt = -1;
   523		s->got = -1;
   524		s->name = mal(l + 1);
   525		memmove(s->name, symb, l);
   526	
   527		s->hash = hash[h];
   528		s->type = 0;
   529		s->version = v;
   530		s->value = 0;
   531		s->sig = 0;
   532		s->size = 0;
   533		hash[h] = s;
   534		nsymbol++;
   535	
   536		s->allsym = allsym;
   537		allsym = s;
   538		return s;
   539	}
   540	
   541	Sym*
   542	lookup(char *name, int v)
   543	{
   544		return _lookup(name, v, 1);
   545	}
   546	
   547	// read-only lookup
   548	Sym*
   549	rlookup(char *name, int v)
   550	{
   551		return _lookup(name, v, 0);
   552	}
   553	
   554	void
   555	copyhistfrog(char *buf, int nbuf)
   556	{
   557		char *p, *ep;
   558		int i;
   559	
   560		p = buf;
   561		ep = buf + nbuf;
   562		for(i=0; i<histfrogp; i++) {
   563			p = seprint(p, ep, "%s", histfrog[i]->name+1);
   564			if(i+1<histfrogp && (p == buf || p[-1] != '/'))
   565				p = seprint(p, ep, "/");
   566		}
   567	}
   568	
   569	void
   570	addhist(int32 line, int type)
   571	{
   572		Auto *u;
   573		Sym *s;
   574		int i, j, k;
   575	
   576		u = mal(sizeof(Auto));
   577		s = mal(sizeof(Sym));
   578		s->name = mal(2*(histfrogp+1) + 1);
   579	
   580		u->asym = s;
   581		u->type = type;
   582		u->aoffset = line;
   583		u->link = curhist;
   584		curhist = u;
   585	
   586		s->name[0] = 0;
   587		j = 1;
   588		for(i=0; i<histfrogp; i++) {
   589			k = histfrog[i]->value;
   590			s->name[j+0] = k>>8;
   591			s->name[j+1] = k;
   592			j += 2;
   593		}
   594		s->name[j] = 0;
   595		s->name[j+1] = 0;
   596	}
   597	
   598	void
   599	histtoauto(void)
   600	{
   601		Auto *l;
   602	
   603		while(l = curhist) {
   604			curhist = l->link;
   605			l->link = curauto;
   606			curauto = l;
   607		}
   608	}
   609	
   610	void
   611	collapsefrog(Sym *s)
   612	{
   613		int i;
   614	
   615		/*
   616		 * bad encoding of path components only allows
   617		 * MAXHIST components. if there is an overflow,
   618		 * first try to collapse xxx/..
   619		 */
   620		for(i=1; i<histfrogp; i++)
   621			if(strcmp(histfrog[i]->name+1, "..") == 0) {
   622				memmove(histfrog+i-1, histfrog+i+1,
   623					(histfrogp-i-1)*sizeof(histfrog[0]));
   624				histfrogp--;
   625				goto out;
   626			}
   627	
   628		/*
   629		 * next try to collapse .
   630		 */
   631		for(i=0; i<histfrogp; i++)
   632			if(strcmp(histfrog[i]->name+1, ".") == 0) {
   633				memmove(histfrog+i, histfrog+i+1,
   634					(histfrogp-i-1)*sizeof(histfrog[0]));
   635				goto out;
   636			}
   637	
   638		/*
   639		 * last chance, just truncate from front
   640		 */
   641		memmove(histfrog+0, histfrog+1,
   642			(histfrogp-1)*sizeof(histfrog[0]));
   643	
   644	out:
   645		histfrog[histfrogp-1] = s;
   646	}
   647	
   648	void
   649	nuxiinit(void)
   650	{
   651		int i, c;
   652	
   653		for(i=0; i<4; i++) {
   654			c = find1(0x04030201L, i+1);
   655			if(i < 2)
   656				inuxi2[i] = c;
   657			if(i < 1)
   658				inuxi1[i] = c;
   659			inuxi4[i] = c;
   660			if(c == i) {
   661				inuxi8[i] = c;
   662				inuxi8[i+4] = c+4;
   663			} else {
   664				inuxi8[i] = c+4;
   665				inuxi8[i+4] = c;
   666			}
   667			fnuxi4[i] = c;
   668			fnuxi8[i] = c;
   669			fnuxi8[i+4] = c+4;
   670		}
   671		if(debug['v']) {
   672			Bprint(&bso, "inuxi = ");
   673			for(i=0; i<1; i++)
   674				Bprint(&bso, "%d", inuxi1[i]);
   675			Bprint(&bso, " ");
   676			for(i=0; i<2; i++)
   677				Bprint(&bso, "%d", inuxi2[i]);
   678			Bprint(&bso, " ");
   679			for(i=0; i<4; i++)
   680				Bprint(&bso, "%d", inuxi4[i]);
   681			Bprint(&bso, " ");
   682			for(i=0; i<8; i++)
   683				Bprint(&bso, "%d", inuxi8[i]);
   684			Bprint(&bso, "\nfnuxi = ");
   685			for(i=0; i<4; i++)
   686				Bprint(&bso, "%d", fnuxi4[i]);
   687			Bprint(&bso, " ");
   688			for(i=0; i<8; i++)
   689				Bprint(&bso, "%d", fnuxi8[i]);
   690			Bprint(&bso, "\n");
   691		}
   692		Bflush(&bso);
   693	}
   694	
   695	int
   696	find1(int32 l, int c)
   697	{
   698		char *p;
   699		int i;
   700	
   701		p = (char*)&l;
   702		for(i=0; i<4; i++)
   703			if(*p++ == c)
   704				return i;
   705		return 0;
   706	}
   707	
   708	int
   709	find2(int32 l, int c)
   710	{
   711		union {
   712			int32 l;
   713			short p[2];
   714		} u;
   715		short *p;
   716		int i;
   717	
   718		u.l = l;
   719		p = u.p;
   720		for(i=0; i<4; i+=2) {
   721			if(((*p >> 8) & 0xff) == c)
   722				return i;
   723			if((*p++ & 0xff) == c)
   724				return i+1;
   725		}
   726		return 0;
   727	}
   728	
   729	int32
   730	ieeedtof(Ieee *e)
   731	{
   732		int exp;
   733		int32 v;
   734	
   735		if(e->h == 0)
   736			return 0;
   737		exp = (e->h>>20) & ((1L<<11)-1L);
   738		exp -= (1L<<10) - 2L;
   739		v = (e->h & 0xfffffL) << 3;
   740		v |= (e->l >> 29) & 0x7L;
   741		if((e->l >> 28) & 1) {
   742			v++;
   743			if(v & 0x800000L) {
   744				v = (v & 0x7fffffL) >> 1;
   745				exp++;
   746			}
   747		}
   748		if(-148 <= exp && exp <= -126) {
   749			v |= 1<<23;
   750			v >>= -125 - exp;
   751			exp = -126;
   752		}
   753		else if(exp < -148 || exp >= 130)
   754			diag("double fp to single fp overflow: %.17g", ieeedtod(e));
   755		v |= ((exp + 126) & 0xffL) << 23;
   756		v |= e->h & 0x80000000L;
   757		return v;
   758	}
   759	
   760	double
   761	ieeedtod(Ieee *ieeep)
   762	{
   763		Ieee e;
   764		double fr;
   765		int exp;
   766	
   767		if(ieeep->h & (1L<<31)) {
   768			e.h = ieeep->h & ~(1L<<31);
   769			e.l = ieeep->l;
   770			return -ieeedtod(&e);
   771		}
   772		if(ieeep->l == 0 && ieeep->h == 0)
   773			return 0;
   774		exp = (ieeep->h>>20) & ((1L<<11)-1L);
   775		exp -= (1L<<10) - 2L;
   776		fr = ieeep->l & ((1L<<16)-1L);
   777		fr /= 1L<<16;
   778		fr += (ieeep->l>>16) & ((1L<<16)-1L);
   779		fr /= 1L<<16;
   780		if(exp == -(1L<<10) - 2L) {
   781			fr += (ieeep->h & (1L<<20)-1L);
   782			exp++;
   783		} else
   784			fr += (ieeep->h & (1L<<20)-1L) | (1L<<20);
   785		fr /= 1L<<21;
   786		return ldexp(fr, exp);
   787	}
   788	
   789	void
   790	zerosig(char *sp)
   791	{
   792		Sym *s;
   793	
   794		s = lookup(sp, 0);
   795		s->sig = 0;
   796	}
   797	
   798	int32
   799	Bget4(Biobuf *f)
   800	{
   801		uchar p[4];
   802	
   803		if(Bread(f, p, 4) != 4)
   804			return 0;
   805		return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
   806	}
   807	
   808	void
   809	mywhatsys(void)
   810	{
   811		goroot = getgoroot();
   812		goos = getgoos();
   813		goarch = thestring;	// ignore $GOARCH - we know who we are
   814	}
   815	
   816	int
   817	pathchar(void)
   818	{
   819		return '/';
   820	}
   821	
   822	static	uchar*	hunk;
   823	static	uint32	nhunk;
   824	#define	NHUNK	(10UL<<20)
   825	
   826	void*
   827	mal(uint32 n)
   828	{
   829		void *v;
   830	
   831		n = (n+7)&~7;
   832		if(n > NHUNK) {
   833			v = malloc(n);
   834			if(v == nil) {
   835				diag("out of memory");
   836				errorexit();
   837			}
   838			memset(v, 0, n);
   839			return v;
   840		}
   841		if(n > nhunk) {
   842			hunk = malloc(NHUNK);
   843			if(hunk == nil) {
   844				diag("out of memory");
   845				errorexit();
   846			}
   847			nhunk = NHUNK;
   848		}
   849	
   850		v = hunk;
   851		nhunk -= n;
   852		hunk += n;
   853	
   854		memset(v, 0, n);
   855		return v;
   856	}
   857	
   858	void
   859	unmal(void *v, uint32 n)
   860	{
   861		n = (n+7)&~7;
   862		if(hunk - n == v) {
   863			hunk -= n;
   864			nhunk += n;
   865		}
   866	}
   867	
   868	// Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
   869	/*
   870	 * Convert raw string to the prefix that will be used in the symbol table.
   871	 * Invalid bytes turn into %xx.	 Right now the only bytes that need
   872	 * escaping are %, ., and ", but we escape all control characters too.
   873	 */
   874	static char*
   875	pathtoprefix(char *s)
   876	{
   877		static char hex[] = "0123456789abcdef";
   878		char *p, *r, *w;
   879		int n;
   880	
   881		// check for chars that need escaping
   882		n = 0;
   883		for(r=s; *r; r++)
   884			if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"')
   885				n++;
   886	
   887		// quick exit
   888		if(n == 0)
   889			return s;
   890	
   891		// escape
   892		p = mal((r-s)+1+2*n);
   893		for(r=s, w=p; *r; r++) {
   894			if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"') {
   895				*w++ = '%';
   896				*w++ = hex[(*r>>4)&0xF];
   897				*w++ = hex[*r&0xF];
   898			} else
   899				*w++ = *r;
   900		}
   901		*w = '\0';
   902		return p;
   903	}
   904	
   905	int
   906	iconv(Fmt *fp)
   907	{
   908		char *p;
   909	
   910		p = va_arg(fp->args, char*);
   911		if(p == nil) {
   912			fmtstrcpy(fp, "<nil>");
   913			return 0;
   914		}
   915		p = pathtoprefix(p);
   916		fmtstrcpy(fp, p);
   917		return 0;
   918	}
   919	
   920	void
   921	mangle(char *file)
   922	{
   923		fprint(2, "%s: mangled input file\n", file);
   924		errorexit();
   925	}
   926	
   927	Section*
   928	addsection(Segment *seg, char *name, int rwx)
   929	{
   930		Section **l;
   931		Section *sect;
   932		
   933		for(l=&seg->sect; *l; l=&(*l)->next)
   934			;
   935		sect = mal(sizeof *sect);
   936		sect->rwx = rwx;
   937		sect->name = name;
   938		sect->seg = seg;
   939		*l = sect;
   940		return sect;
   941	}
   942	
   943	void
   944	pclntab(void)
   945	{
   946		vlong oldpc;
   947		Prog *p;
   948		int32 oldlc, v, s;
   949		Sym *sym;
   950		uchar *bp;
   951		
   952		sym = lookup("pclntab", 0);
   953		sym->type = SPCLNTAB;
   954		sym->reachable = 1;
   955		if(debug['s'])
   956			return;
   957	
   958		oldpc = INITTEXT;
   959		oldlc = 0;
   960		for(cursym = textp; cursym != nil; cursym = cursym->next) {
   961			for(p = cursym->text; p != P; p = p->link) {
   962				if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
   963					if(debug['O'])
   964						Bprint(&bso, "%6llux %P\n",
   965							(vlong)p->pc, p);
   966					continue;
   967				}
   968				if(debug['O'])
   969					Bprint(&bso, "\t\t%6d", lcsize);
   970				v = (p->pc - oldpc) / MINLC;
   971				while(v) {
   972					s = 127;
   973					if(v < 127)
   974						s = v;
   975					symgrow(sym, lcsize+1);
   976					bp = sym->p + lcsize;
   977					*bp = s+128;	/* 129-255 +pc */
   978					if(debug['O'])
   979						Bprint(&bso, " pc+%d*%d(%d)", s, MINLC, s+128);
   980					v -= s;
   981					lcsize++;
   982				}
   983				s = p->line - oldlc;
   984				oldlc = p->line;
   985				oldpc = p->pc + MINLC;
   986				if(s > 64 || s < -64) {
   987					symgrow(sym, lcsize+5);
   988					bp = sym->p + lcsize;
   989					*bp++ = 0;	/* 0 vv +lc */
   990					*bp++ = s>>24;
   991					*bp++ = s>>16;
   992					*bp++ = s>>8;
   993					*bp = s;
   994					if(debug['O']) {
   995						if(s > 0)
   996							Bprint(&bso, " lc+%d(%d,%d)\n",
   997								s, 0, s);
   998						else
   999							Bprint(&bso, " lc%d(%d,%d)\n",
  1000								s, 0, s);
  1001						Bprint(&bso, "%6llux %P\n",
  1002							(vlong)p->pc, p);
  1003					}
  1004					lcsize += 5;
  1005					continue;
  1006				}
  1007				symgrow(sym, lcsize+1);
  1008				bp = sym->p + lcsize;
  1009				if(s > 0) {
  1010					*bp = 0+s;	/* 1-64 +lc */
  1011					if(debug['O']) {
  1012						Bprint(&bso, " lc+%d(%d)\n", s, 0+s);
  1013						Bprint(&bso, "%6llux %P\n",
  1014							(vlong)p->pc, p);
  1015					}
  1016				} else {
  1017					*bp = 64-s;	/* 65-128 -lc */
  1018					if(debug['O']) {
  1019						Bprint(&bso, " lc%d(%d)\n", s, 64-s);
  1020						Bprint(&bso, "%6llux %P\n",
  1021							(vlong)p->pc, p);
  1022					}
  1023				}
  1024				lcsize++;
  1025			}
  1026		}
  1027		if(lcsize & 1) {
  1028			symgrow(sym, lcsize+1);
  1029			sym->p[lcsize] = 129;
  1030			lcsize++;
  1031		}
  1032		sym->size = lcsize;
  1033		lcsize = 0;
  1034	
  1035		if(debug['v'] || debug['O'])
  1036			Bprint(&bso, "lcsize = %d\n", lcsize);
  1037		Bflush(&bso);
  1038	}
  1039	
  1040	#define	LOG	5
  1041	void
  1042	mkfwd(void)
  1043	{
  1044		Prog *p;
  1045		int i;
  1046		int32 dwn[LOG], cnt[LOG];
  1047		Prog *lst[LOG];
  1048	
  1049		for(i=0; i<LOG; i++) {
  1050			if(i == 0)
  1051				cnt[i] = 1;
  1052			else
  1053				cnt[i] = LOG * cnt[i-1];
  1054			dwn[i] = 1;
  1055			lst[i] = P;
  1056		}
  1057		i = 0;
  1058		for(cursym = textp; cursym != nil; cursym = cursym->next) {
  1059			for(p = cursym->text; p != P; p = p->link) {
  1060				if(p->link == P) {
  1061					if(cursym->next)
  1062						p->forwd = cursym->next->text;
  1063					break;
  1064				}
  1065				i--;
  1066				if(i < 0)
  1067					i = LOG-1;
  1068				p->forwd = P;
  1069				dwn[i]--;
  1070				if(dwn[i] <= 0) {
  1071					dwn[i] = cnt[i];
  1072					if(lst[i] != P)
  1073						lst[i]->forwd = p;
  1074					lst[i] = p;
  1075				}
  1076			}
  1077		}
  1078	}
  1079	
  1080	uint16
  1081	le16(uchar *b)
  1082	{
  1083		return b[0] | b[1]<<8;
  1084	}
  1085	
  1086	uint32
  1087	le32(uchar *b)
  1088	{
  1089		return b[0] | b[1]<<8 | b[2]<<16 | b[3]<<24;
  1090	}
  1091	
  1092	uint64
  1093	le64(uchar *b)
  1094	{
  1095		return le32(b) | (uint64)le32(b+4)<<32;
  1096	}
  1097	
  1098	uint16
  1099	be16(uchar *b)
  1100	{
  1101		return b[0]<<8 | b[1];
  1102	}
  1103	
  1104	uint32
  1105	be32(uchar *b)
  1106	{
  1107		return b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
  1108	}
  1109	
  1110	uint64
  1111	be64(uchar *b)
  1112	{
  1113		return (uvlong)be32(b)<<32 | be32(b+4);
  1114	}
  1115	
  1116	Endian be = { be16, be32, be64 };
  1117	Endian le = { le16, le32, le64 };
  1118	
  1119	typedef struct Chain Chain;
  1120	struct Chain
  1121	{
  1122		Sym *sym;
  1123		Chain *up;
  1124		int limit;  // limit on entry to sym
  1125	};
  1126	
  1127	static int stkcheck(Chain*, int);
  1128	static void stkprint(Chain*, int);
  1129	static void stkbroke(Chain*, int);
  1130	static Sym *morestack;
  1131	static Sym *newstack;
  1132	
  1133	enum
  1134	{
  1135		HasLinkRegister = (thechar == '5'),
  1136		CallSize = (!HasLinkRegister)*PtrSize,	// bytes of stack required for a call
  1137	};
  1138	
  1139	void
  1140	dostkcheck(void)
  1141	{
  1142		Chain ch;
  1143		Sym *s;
  1144		
  1145		morestack = lookup("runtime.morestack", 0);
  1146		newstack = lookup("runtime.newstack", 0);
  1147	
  1148		// First the nosplits on their own.
  1149		for(s = textp; s != nil; s = s->next) {
  1150			if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) == 0)
  1151				continue;
  1152			cursym = s;
  1153			ch.up = nil;
  1154			ch.sym = s;
  1155			ch.limit = StackLimit - CallSize;
  1156			stkcheck(&ch, 0);
  1157			s->stkcheck = 1;
  1158		}
  1159		
  1160		// Check calling contexts.
  1161		// Some nosplits get called a little further down,
  1162		// like newproc and deferproc.	We could hard-code
  1163		// that knowledge but it's more robust to look at
  1164		// the actual call sites.
  1165		for(s = textp; s != nil; s = s->next) {
  1166			if(s->text == nil || s->text->link == nil || (s->text->textflag & NOSPLIT) != 0)
  1167				continue;
  1168			cursym = s;
  1169			ch.up = nil;
  1170			ch.sym = s;
  1171			ch.limit = StackLimit - CallSize;
  1172			stkcheck(&ch, 0);
  1173		}
  1174	}
  1175	
  1176	static int
  1177	stkcheck(Chain *up, int depth)
  1178	{
  1179		Chain ch, ch1;
  1180		Prog *p;
  1181		Sym *s;
  1182		int limit, prolog;
  1183		
  1184		limit = up->limit;
  1185		s = up->sym;
  1186		p = s->text;
  1187		
  1188		// Small optimization: don't repeat work at top.
  1189		if(s->stkcheck && limit == StackLimit-CallSize)
  1190			return 0;
  1191		
  1192		if(depth > 100) {
  1193			diag("nosplit stack check too deep");
  1194			stkbroke(up, 0);
  1195			return -1;
  1196		}
  1197	
  1198		if(p == nil || p->link == nil) {
  1199			// external function.
  1200			// should never be called directly.
  1201			// only diagnose the direct caller.
  1202			if(depth == 1)
  1203				diag("call to external function %s", s->name);
  1204			return -1;
  1205		}
  1206	
  1207		if(limit < 0) {
  1208			stkbroke(up, limit);
  1209			return -1;
  1210		}
  1211	
  1212		// morestack looks like it calls functions,
  1213		// but it switches the stack pointer first.
  1214		if(s == morestack)
  1215			return 0;
  1216	
  1217		ch.up = up;
  1218		prolog = (s->text->textflag & NOSPLIT) == 0;
  1219		for(p = s->text; p != P; p = p->link) {
  1220			limit -= p->spadj;
  1221			if(prolog && p->spadj != 0) {
  1222				// The first stack adjustment in a function with a
  1223				// split-checking prologue marks the end of the
  1224				// prologue.  Assuming the split check is correct,
  1225				// after the adjustment there should still be at least
  1226				// StackLimit bytes available below the stack pointer.
  1227				// If this is not the top call in the chain, no need
  1228				// to duplicate effort, so just stop.
  1229				if(depth > 0)
  1230					return 0;
  1231				prolog = 0;
  1232				limit = StackLimit;
  1233			}
  1234			if(limit < 0) {
  1235				stkbroke(up, limit);
  1236				return -1;
  1237			}
  1238			if(iscall(p)) {
  1239				limit -= CallSize;
  1240				ch.limit = limit;
  1241				if(p->to.type == D_BRANCH) {
  1242					// Direct call.
  1243					ch.sym = p->to.sym;
  1244					if(stkcheck(&ch, depth+1) < 0)
  1245						return -1;
  1246				} else {
  1247					// Indirect call.  Assume it is a splitting function,
  1248					// so we have to make sure it can call morestack.
  1249					limit -= CallSize;
  1250					ch.sym = nil;
  1251					ch1.limit = limit;
  1252					ch1.up = &ch;
  1253					ch1.sym = morestack;
  1254					if(stkcheck(&ch1, depth+2) < 0)
  1255						return -1;
  1256					limit += CallSize;
  1257				}
  1258				limit += CallSize;
  1259			}
  1260			
  1261		}
  1262		return 0;
  1263	}
  1264	
  1265	static void
  1266	stkbroke(Chain *ch, int limit)
  1267	{
  1268		diag("nosplit stack overflow");
  1269		stkprint(ch, limit);
  1270	}
  1271	
  1272	static void
  1273	stkprint(Chain *ch, int limit)
  1274	{
  1275		char *name;
  1276	
  1277		if(ch->sym)
  1278			name = ch->sym->name;
  1279		else
  1280			name = "function pointer";
  1281	
  1282		if(ch->up == nil) {
  1283			// top of chain.  ch->sym != nil.
  1284			if(ch->sym->text->textflag & NOSPLIT)
  1285				print("\t%d\tassumed on entry to %s\n", ch->limit, name);
  1286			else
  1287				print("\t%d\tguaranteed after split check in %s\n", ch->limit, name);
  1288		} else {
  1289			stkprint(ch->up, ch->limit + (!HasLinkRegister)*PtrSize);
  1290			if(!HasLinkRegister)
  1291				print("\t%d\ton entry to %s\n", ch->limit, name);
  1292		}
  1293		if(ch->limit != limit)
  1294			print("\t%d\tafter %s uses %d\n", limit, name, ch->limit - limit);
  1295	}
  1296	
  1297	int
  1298	headtype(char *name)
  1299	{
  1300		int i;
  1301	
  1302		for(i=0; headers[i].name; i++)
  1303			if(strcmp(name, headers[i].name) == 0) {
  1304				headstring = headers[i].name;
  1305				return headers[i].val;
  1306			}
  1307		fprint(2, "unknown header type -H %s\n", name);
  1308		errorexit();
  1309		return -1;  // not reached
  1310	}
  1311	
  1312	void
  1313	undef(void)
  1314	{
  1315		Sym *s;
  1316	
  1317		for(s = allsym; s != S; s = s->allsym)
  1318			if(s->type == SXREF)
  1319				diag("%s(%d): not defined", s->name, s->version);
  1320	}
  1321	
  1322	int
  1323	Yconv(Fmt *fp)
  1324	{
  1325		Sym *s;
  1326		Fmt fmt;
  1327		int i;
  1328		char *str;
  1329	
  1330		s = va_arg(fp->args, Sym*);
  1331		if (s == S) {
  1332			fmtprint(fp, "<nil>");
  1333		} else {
  1334			fmtstrinit(&fmt);
  1335			fmtprint(&fmt, "%s @0x%08x [%d]", s->name, s->value, s->size);
  1336			for (i = 0; i < s->size; i++) {
  1337				if (!(i%8)) fmtprint(&fmt,  "\n\t0x%04x ", i);
  1338				fmtprint(&fmt, "%02x ", s->p[i]);
  1339			}
  1340			fmtprint(&fmt, "\n");
  1341			for (i = 0; i < s->nr; i++) {
  1342				fmtprint(&fmt, "\t0x%04x[%x] %d %s[%llx]\n",
  1343				      s->r[i].off,
  1344				      s->r[i].siz,
  1345				      s->r[i].type,
  1346				      s->r[i].sym->name,
  1347				      (vlong)s->r[i].add);
  1348			}
  1349			str = fmtstrflush(&fmt);
  1350			fmtstrcpy(fp, str);
  1351			free(str);
  1352		}
  1353	
  1354		return 0;
  1355	}
  1356	
  1357	vlong coutpos;
  1358	
  1359	void
  1360	cflush(void)
  1361	{
  1362		int n;
  1363	
  1364		if(cbpmax < cbp)
  1365			cbpmax = cbp;
  1366		n = cbpmax - buf.cbuf;
  1367		if(n) {
  1368			if(write(cout, buf.cbuf, n) != n) {
  1369				diag("write error: %r");
  1370				errorexit();
  1371			}
  1372			coutpos += n;
  1373		}
  1374		cbp = buf.cbuf;
  1375		cbc = sizeof(buf.cbuf);
  1376		cbpmax = cbp;
  1377	}
  1378	
  1379	vlong
  1380	cpos(void)
  1381	{
  1382		return coutpos + cbp - buf.cbuf;
  1383	}
  1384	
  1385	void
  1386	cseek(vlong p)
  1387	{
  1388		vlong start;
  1389		int delta;
  1390	
  1391		if(cbpmax < cbp)
  1392			cbpmax = cbp;
  1393		start = coutpos;
  1394		if(start <= p && p <= start+(cbpmax - buf.cbuf)) {
  1395	//print("cseek %lld in [%lld,%lld] (%lld)\n", p, start, start+sizeof(buf.cbuf), cpos());
  1396			delta = p - (start + cbp - buf.cbuf);
  1397			cbp += delta;
  1398			cbc -= delta;
  1399	//print("now at %lld\n", cpos());
  1400			return;
  1401		}
  1402	
  1403		cflush();
  1404		seek(cout, p, 0);
  1405		coutpos = p;
  1406	}
  1407	
  1408	void
  1409	cwrite(void *buf, int n)
  1410	{
  1411		cflush();
  1412		if(write(cout, buf, n) != n) {
  1413			diag("write error: %r");
  1414			errorexit();
  1415		}
  1416		coutpos += n;
  1417	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.