github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/src/liblink/ld.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 <u.h>
    33  #include <libc.h>
    34  #include <bio.h>
    35  #include <link.h>
    36  
    37  void
    38  addlib(Link *ctxt, char *src, char *obj, char *pathname)
    39  {
    40  	char name[1024], pname[1024], *p;
    41  	int i;
    42  
    43  	if(strlen(pathname) >= sizeof name)
    44  		sysfatal("addlib pathname too long");
    45  	strcpy(name, pathname);
    46  	cleanname(name);
    47  	
    48  	// runtime.a -> runtime
    49  	p = nil;
    50  	if(strlen(name) > 2 && name[strlen(name)-2] == '.') {
    51  		p = name+strlen(name)-2;
    52  		*p = '\0';
    53  	}
    54  	
    55  	// already loaded?
    56  	for(i=0; i<ctxt->libraryp; i++)
    57  		if(strcmp(ctxt->library[i].pkg, name) == 0)
    58  			return;
    59  	
    60  	// runtime -> runtime.a for search
    61  	if(p != nil)
    62  		*p = '.';
    63  
    64  	if((!ctxt->windows && name[0] == '/') || (ctxt->windows && name[1] == ':'))
    65  		snprint(pname, sizeof pname, "%s", name);
    66  	else {
    67  		// try dot, -L "libdir", and then goroot.
    68  		for(i=0; i<ctxt->nlibdir; i++) {
    69  			snprint(pname, sizeof pname, "%s/%s", ctxt->libdir[i], name);
    70  			if(access(pname, AEXIST) >= 0)
    71  				break;
    72  		}
    73  	}
    74  	cleanname(pname);
    75  
    76  	/* runtime.a -> runtime */
    77  	if(p != nil)
    78  		*p = '\0';
    79  
    80  	if(ctxt->debugvlog > 1 && ctxt->bso)
    81  		Bprint(ctxt->bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
    82  
    83  	addlibpath(ctxt, src, obj, pname, name);
    84  }
    85  
    86  /*
    87   * add library to library list.
    88   *	srcref: src file referring to package
    89   *	objref: object file referring to package
    90   *	file: object file, e.g., /home/rsc/go/pkg/container/vector.a
    91   *	pkg: package import path, e.g. container/vector
    92   */
    93  void
    94  addlibpath(Link *ctxt, char *srcref, char *objref, char *file, char *pkg)
    95  {
    96  	int i;
    97  	Library *l;
    98  
    99  	for(i=0; i<ctxt->libraryp; i++)
   100  		if(strcmp(file, ctxt->library[i].file) == 0)
   101  			return;
   102  
   103  	if(ctxt->debugvlog > 1 && ctxt->bso)
   104  		Bprint(ctxt->bso, "%5.2f addlibpath: srcref: %s objref: %s file: %s pkg: %s\n",
   105  			cputime(), srcref, objref, file, pkg);
   106  
   107  	if(ctxt->libraryp == ctxt->nlibrary){
   108  		ctxt->nlibrary = 50 + 2*ctxt->libraryp;
   109  		ctxt->library = erealloc(ctxt->library, sizeof ctxt->library[0] * ctxt->nlibrary);
   110  	}
   111  
   112  	l = &ctxt->library[ctxt->libraryp++];
   113  	l->objref = estrdup(objref);
   114  	l->srcref = estrdup(srcref);
   115  	l->file = estrdup(file);
   116  	l->pkg = estrdup(pkg);
   117  }
   118  
   119  int
   120  find1(int32 l, int c)
   121  {
   122  	char *p;
   123  	int i;
   124  
   125  	p = (char*)&l;
   126  	for(i=0; i<4; i++)
   127  		if(*p++ == c)
   128  			return i;
   129  	return 0;
   130  }
   131  
   132  void
   133  nuxiinit(void)
   134  {
   135  	int i, c;
   136  
   137  	for(i=0; i<4; i++) {
   138  		c = find1(0x04030201L, i+1);
   139  		if(i < 2)
   140  			inuxi2[i] = c;
   141  		if(i < 1)
   142  			inuxi1[i] = c;
   143  		inuxi4[i] = c;
   144  		if(c == i) {
   145  			inuxi8[i] = c;
   146  			inuxi8[i+4] = c+4;
   147  		} else {
   148  			inuxi8[i] = c+4;
   149  			inuxi8[i+4] = c;
   150  		}
   151  		fnuxi4[i] = c;
   152  		fnuxi8[i] = c;
   153  		fnuxi8[i+4] = c+4;
   154  	}
   155  }
   156  
   157  uchar	fnuxi8[8];
   158  uchar	fnuxi4[4];
   159  uchar	inuxi1[1];
   160  uchar	inuxi2[2];
   161  uchar	inuxi4[4];
   162  uchar	inuxi8[8];
   163  
   164  #define	LOG	5
   165  void
   166  mkfwd(LSym *sym)
   167  {
   168  	Prog *p;
   169  	int i;
   170  	int32 dwn[LOG], cnt[LOG];
   171  	Prog *lst[LOG];
   172  
   173  	for(i=0; i<LOG; i++) {
   174  		if(i == 0)
   175  			cnt[i] = 1;
   176  		else
   177  			cnt[i] = LOG * cnt[i-1];
   178  		dwn[i] = 1;
   179  		lst[i] = nil;
   180  	}
   181  	i = 0;
   182  	for(p = sym->text; p != nil && p->link != nil; p = p->link) {
   183  		i--;
   184  		if(i < 0)
   185  			i = LOG-1;
   186  		p->forwd = nil;
   187  		dwn[i]--;
   188  		if(dwn[i] <= 0) {
   189  			dwn[i] = cnt[i];
   190  			if(lst[i] != nil)
   191  				lst[i]->forwd = p;
   192  			lst[i] = p;
   193  		}
   194  	}
   195  }
   196  
   197  Prog*
   198  copyp(Link *ctxt, Prog *q)
   199  {
   200  	Prog *p;
   201  
   202  	p = ctxt->arch->prg();
   203  	*p = *q;
   204  	return p;
   205  }
   206  
   207  Prog*
   208  appendp(Link *ctxt, Prog *q)
   209  {
   210  	Prog *p;
   211  
   212  	p = ctxt->arch->prg();
   213  	p->link = q->link;
   214  	q->link = p;
   215  	p->lineno = q->lineno;
   216  	p->mode = q->mode;
   217  	return p;
   218  }
   219  
   220  vlong
   221  atolwhex(char *s)
   222  {
   223  	vlong n;
   224  	int f;
   225  
   226  	n = 0;
   227  	f = 0;
   228  	while(*s == ' ' || *s == '\t')
   229  		s++;
   230  	if(*s == '-' || *s == '+') {
   231  		if(*s++ == '-')
   232  			f = 1;
   233  		while(*s == ' ' || *s == '\t')
   234  			s++;
   235  	}
   236  	if(s[0]=='0' && s[1]){
   237  		if(s[1]=='x' || s[1]=='X'){
   238  			s += 2;
   239  			for(;;){
   240  				if(*s >= '0' && *s <= '9')
   241  					n = n*16 + *s++ - '0';
   242  				else if(*s >= 'a' && *s <= 'f')
   243  					n = n*16 + *s++ - 'a' + 10;
   244  				else if(*s >= 'A' && *s <= 'F')
   245  					n = n*16 + *s++ - 'A' + 10;
   246  				else
   247  					break;
   248  			}
   249  		} else
   250  			while(*s >= '0' && *s <= '7')
   251  				n = n*8 + *s++ - '0';
   252  	} else
   253  		while(*s >= '0' && *s <= '9')
   254  			n = n*10 + *s++ - '0';
   255  	if(f)
   256  		n = -n;
   257  	return n;
   258  }