github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/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(LinkArch *arch) 134 { 135 int i, c; 136 137 if(arch->endian != BigEndian && arch->endian != LittleEndian) 138 sysfatal("unknown endian (%#x) for arch %s", arch->endian, arch->name); 139 140 for(i=0; i<4; i++) { 141 c = find1(arch->endian, i+1); 142 if(arch->endian == LittleEndian) { 143 if(i < 2) 144 inuxi2[i] = c; 145 if(i < 1) 146 inuxi1[i] = c; 147 } else { 148 if(i >= 2) 149 inuxi2[i-2] = c; 150 if(i >= 3) 151 inuxi1[i-3] = c; 152 } 153 inuxi4[i] = c; 154 if(c == i) { 155 inuxi8[i] = c; 156 inuxi8[i+4] = c+4; 157 } else { 158 inuxi8[i] = c+4; 159 inuxi8[i+4] = c; 160 } 161 fnuxi4[i] = c; 162 if(c == i) { 163 fnuxi8[i] = c; 164 fnuxi8[i+4] = c+4; 165 } else { 166 fnuxi8[i] = c+4; 167 fnuxi8[i+4] = c; 168 } 169 } 170 } 171 172 uchar fnuxi8[8]; 173 uchar fnuxi4[4]; 174 uchar inuxi1[1]; 175 uchar inuxi2[2]; 176 uchar inuxi4[4]; 177 uchar inuxi8[8]; 178 179 enum 180 { 181 LOG = 5, 182 }; 183 void 184 mkfwd(LSym *sym) 185 { 186 Prog *p; 187 int i; 188 int32 dwn[LOG], cnt[LOG]; 189 Prog *lst[LOG]; 190 191 for(i=0; i<LOG; i++) { 192 if(i == 0) 193 cnt[i] = 1; 194 else 195 cnt[i] = LOG * cnt[i-1]; 196 dwn[i] = 1; 197 lst[i] = nil; 198 } 199 i = 0; 200 for(p = sym->text; p != nil && p->link != nil; p = p->link) { 201 i--; 202 if(i < 0) 203 i = LOG-1; 204 p->forwd = nil; 205 dwn[i]--; 206 if(dwn[i] <= 0) { 207 dwn[i] = cnt[i]; 208 if(lst[i] != nil) 209 lst[i]->forwd = p; 210 lst[i] = p; 211 } 212 } 213 } 214 215 Prog* 216 copyp(Link *ctxt, Prog *q) 217 { 218 Prog *p; 219 220 p = ctxt->arch->prg(); 221 *p = *q; 222 return p; 223 } 224 225 Prog* 226 appendp(Link *ctxt, Prog *q) 227 { 228 Prog *p; 229 230 p = ctxt->arch->prg(); 231 p->link = q->link; 232 q->link = p; 233 p->lineno = q->lineno; 234 p->mode = q->mode; 235 return p; 236 } 237 238 vlong 239 atolwhex(char *s) 240 { 241 vlong n; 242 int f; 243 244 n = 0; 245 f = 0; 246 while(*s == ' ' || *s == '\t') 247 s++; 248 if(*s == '-' || *s == '+') { 249 if(*s++ == '-') 250 f = 1; 251 while(*s == ' ' || *s == '\t') 252 s++; 253 } 254 if(s[0]=='0' && s[1]){ 255 if(s[1]=='x' || s[1]=='X'){ 256 s += 2; 257 for(;;){ 258 if(*s >= '0' && *s <= '9') 259 n = n*16 + *s++ - '0'; 260 else if(*s >= 'a' && *s <= 'f') 261 n = n*16 + *s++ - 'a' + 10; 262 else if(*s >= 'A' && *s <= 'F') 263 n = n*16 + *s++ - 'A' + 10; 264 else 265 break; 266 } 267 } else 268 while(*s >= '0' && *s <= '7') 269 n = n*8 + *s++ - '0'; 270 } else 271 while(*s >= '0' && *s <= '9') 272 n = n*10 + *s++ - '0'; 273 if(f) 274 n = -n; 275 return n; 276 }