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 }