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 }