LEFT | RIGHT |
1 // Derived from Inferno utils/6l/obj.c and utils/6l/span.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 | 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 | 3 // http://code.google.com/p/inferno-os/source/browse/utils/6l/span.c |
4 // | 4 // |
5 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. | 5 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. |
6 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) | 6 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) |
7 // Portions Copyright © 1997-1999 Vita Nuova Limited | 7 // Portions Copyright © 1997-1999 Vita Nuova Limited |
8 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) | 8 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuov
a.com) |
9 // Portions Copyright © 2004,2006 Bruce Ellis | 9 // Portions Copyright © 2004,2006 Bruce Ellis |
10 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) | 10 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 76 |
77 fmtinstall('i', iconv); | 77 fmtinstall('i', iconv); |
78 fmtinstall('Y', Yconv); | 78 fmtinstall('Y', Yconv); |
79 fmtinstall('Z', Zconv); | 79 fmtinstall('Z', Zconv); |
80 mywhatsys(); // get goroot, goarch, goos | 80 mywhatsys(); // get goroot, goarch, goos |
81 if(strcmp(goarch, thestring) != 0) | 81 if(strcmp(goarch, thestring) != 0) |
82 print("goarch is not known: %s\n", goarch); | 82 print("goarch is not known: %s\n", goarch); |
83 | 83 |
84 // add goroot to the end of the libdir list. | 84 // add goroot to the end of the libdir list. |
85 race = ""; | 85 race = ""; |
86 » if(debug['b']) | 86 » if(flag_race) |
87 race = "_race"; | 87 race = "_race"; |
88 Lflag(smprint("%s/pkg/%s_%s%s", goroot, goos, goarch, race)); | 88 Lflag(smprint("%s/pkg/%s_%s%s", goroot, goos, goarch, race)); |
89 | 89 |
90 // Unix doesn't like it when we write to a running (or, sometimes, | 90 // Unix doesn't like it when we write to a running (or, sometimes, |
91 // recently run) binary, so remove the output file before writing it. | 91 // recently run) binary, so remove the output file before writing it. |
92 // On Windows 7, remove() can force the following create() to fail. | 92 // On Windows 7, remove() can force the following create() to fail. |
93 #ifndef _WIN32 | 93 #ifndef _WIN32 |
94 remove(outfile); | 94 remove(outfile); |
95 #endif | 95 #endif |
96 cout = create(outfile, 1, 0775); | 96 cout = create(outfile, 1, 0775); |
97 if(cout < 0) { | 97 if(cout < 0) { |
98 diag("cannot create %s", outfile); | 98 diag("cannot create %s", outfile); |
99 errorexit(); | 99 errorexit(); |
100 } | 100 } |
101 | 101 |
102 if(INITENTRY == nil) { | 102 if(INITENTRY == nil) { |
103 INITENTRY = mal(strlen(goarch)+strlen(goos)+10); | 103 INITENTRY = mal(strlen(goarch)+strlen(goos)+10); |
104 sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); | 104 sprint(INITENTRY, "_rt0_%s_%s", goarch, goos); |
105 } | 105 } |
106 lookup(INITENTRY, 0)->type = SXREF; | 106 lookup(INITENTRY, 0)->type = SXREF; |
107 » if (debug['U']) { | 107 » if(flag_shared) { |
108 if(LIBINITENTRY == nil) { | 108 if(LIBINITENTRY == nil) { |
109 LIBINITENTRY = mal(strlen(goarch)+strlen(goos)+20); | 109 LIBINITENTRY = mal(strlen(goarch)+strlen(goos)+20); |
110 sprint(LIBINITENTRY, "_rt0_%s_%s_lib", goarch, goos); | 110 sprint(LIBINITENTRY, "_rt0_%s_%s_lib", goarch, goos); |
111 } | 111 } |
112 lookup(LIBINITENTRY, 0)->type = SXREF; | 112 lookup(LIBINITENTRY, 0)->type = SXREF; |
113 } | 113 } |
114 } | 114 } |
115 | 115 |
116 void | 116 void |
117 errorexit(void) | 117 errorexit(void) |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 } | 286 } |
287 | 287 |
288 void | 288 void |
289 loadlib(void) | 289 loadlib(void) |
290 { | 290 { |
291 int i; | 291 int i; |
292 | 292 |
293 loadinternal("runtime"); | 293 loadinternal("runtime"); |
294 if(thechar == '5') | 294 if(thechar == '5') |
295 loadinternal("math"); | 295 loadinternal("math"); |
296 » if(debug['b']) | 296 » if(flag_race) |
297 loadinternal("runtime/race"); | 297 loadinternal("runtime/race"); |
298 | 298 |
299 for(i=0; i<libraryp; i++) { | 299 for(i=0; i<libraryp; i++) { |
300 if(debug['v']) | 300 if(debug['v']) |
301 Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(),
library[i].file, library[i].objref); | 301 Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(),
library[i].file, library[i].objref); |
302 iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0; | 302 iscgo |= strcmp(library[i].pkg, "runtime/cgo") == 0; |
303 objfile(library[i].file, library[i].pkg); | 303 objfile(library[i].file, library[i].pkg); |
304 } | 304 } |
305 ········ | 305 ········ |
306 // We've loaded all the code now. | 306 // We've loaded all the code now. |
307 // If there are no dynamic libraries needed, gcc disables dynamic linkin
g. | 307 // If there are no dynamic libraries needed, gcc disables dynamic linkin
g. |
308 // Because of this, glibc's dynamic ELF loader occasionally (like in ver
sion 2.13) | 308 // Because of this, glibc's dynamic ELF loader occasionally (like in ver
sion 2.13) |
309 // assumes that a dynamic binary always refers to at least one dynamic l
ibrary. | 309 // assumes that a dynamic binary always refers to at least one dynamic l
ibrary. |
310 // Rather than be a source of test cases for glibc, disable dynamic link
ing | 310 // Rather than be a source of test cases for glibc, disable dynamic link
ing |
311 // the same way that gcc would. | 311 // the same way that gcc would. |
312 // | 312 // |
313 // Exception: on OS X, programs such as Shark only work with dynamic | 313 // Exception: on OS X, programs such as Shark only work with dynamic |
314 // binaries, so leave it enabled on OS X (Mach-O) binaries. | 314 // binaries, so leave it enabled on OS X (Mach-O) binaries. |
315 » if(!debug['U'] && !havedynamic && HEADTYPE != Hdarwin) | 315 » if(!flag_shared && !havedynamic && HEADTYPE != Hdarwin) |
316 debug['d'] = 1; | 316 debug['d'] = 1; |
317 ········ | 317 ········ |
318 importcycles(); | 318 importcycles(); |
319 sortdynexp(); | 319 sortdynexp(); |
320 } | 320 } |
321 | 321 |
322 /* | 322 /* |
323 * look for the next file in an archive. | 323 * look for the next file in an archive. |
324 * adapted from libmach. | 324 * adapted from libmach. |
325 */ | 325 */ |
(...skipping 1175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 { | 1501 { |
1502 cflush(); | 1502 cflush(); |
1503 if(n <= 0) | 1503 if(n <= 0) |
1504 return; | 1504 return; |
1505 if(write(cout, buf, n) != n) { | 1505 if(write(cout, buf, n) != n) { |
1506 diag("write error: %r"); | 1506 diag("write error: %r"); |
1507 errorexit(); | 1507 errorexit(); |
1508 } | 1508 } |
1509 coutpos += n; | 1509 coutpos += n; |
1510 } | 1510 } |
| 1511 |
| 1512 void |
| 1513 usage(void) |
| 1514 { |
| 1515 fprint(2, "usage: %cl [options] main.%c\n", thechar, thechar); |
| 1516 flagprint(2); |
| 1517 exits("usage"); |
| 1518 } |
| 1519 |
| 1520 void |
| 1521 setheadtype(char *s) |
| 1522 { |
| 1523 HEADTYPE = headtype(s); |
| 1524 } |
| 1525 |
| 1526 void |
| 1527 setinterp(char *s) |
| 1528 { |
| 1529 debug['I'] = 1; // denote cmdline interpreter override |
| 1530 interpreter = s; |
| 1531 } |
| 1532 |
| 1533 void |
| 1534 doversion(void) |
| 1535 { |
| 1536 print("%cl version %s\n", thechar, getgoversion()); |
| 1537 errorexit(); |
| 1538 } |
| 1539 |
| 1540 void |
| 1541 genasmsym(void (*put)(Sym*, char*, int, vlong, vlong, int, Sym*)) |
| 1542 { |
| 1543 Auto *a; |
| 1544 Sym *s; |
| 1545 |
| 1546 // These symbols won't show up in the first loop below because we |
| 1547 // skip STEXT symbols. Normal STEXT symbols are emitted by walking textp
. |
| 1548 s = lookup("text", 0); |
| 1549 if(s->type == STEXT) |
| 1550 put(s, s->name, 'T', s->value, s->size, s->version, 0); |
| 1551 s = lookup("etext", 0); |
| 1552 if(s->type == STEXT) |
| 1553 put(s, s->name, 'T', s->value, s->size, s->version, 0); |
| 1554 |
| 1555 for(s=allsym; s!=S; s=s->allsym) { |
| 1556 if(s->hide) |
| 1557 continue; |
| 1558 switch(s->type&SMASK) { |
| 1559 case SCONST: |
| 1560 case SRODATA: |
| 1561 case SSYMTAB: |
| 1562 case SPCLNTAB: |
| 1563 case SDATA: |
| 1564 case SNOPTRDATA: |
| 1565 case SELFROSECT: |
| 1566 case SMACHOGOT: |
| 1567 case STYPE: |
| 1568 case SSTRING: |
| 1569 case SGOSTRING: |
| 1570 case SWINDOWS: |
| 1571 case SGCDATA: |
| 1572 case SGCBSS: |
| 1573 if(!s->reachable) |
| 1574 continue; |
| 1575 put(s, s->name, 'D', symaddr(s), s->size, s->version, s-
>gotype); |
| 1576 continue; |
| 1577 |
| 1578 case SBSS: |
| 1579 case SNOPTRBSS: |
| 1580 if(!s->reachable) |
| 1581 continue; |
| 1582 if(s->np > 0) |
| 1583 diag("%s should not be bss (size=%d type=%d spec
ial=%d)", s->name, (int)s->np, s->type, s->special); |
| 1584 put(s, s->name, 'B', symaddr(s), s->size, s->version, s-
>gotype); |
| 1585 continue; |
| 1586 |
| 1587 case SFILE: |
| 1588 put(nil, s->name, 'f', s->value, 0, s->version, 0); |
| 1589 continue; |
| 1590 } |
| 1591 } |
| 1592 |
| 1593 for(s = textp; s != nil; s = s->next) { |
| 1594 if(s->text == nil) |
| 1595 continue; |
| 1596 |
| 1597 /* filenames first */ |
| 1598 for(a=s->autom; a; a=a->link) |
| 1599 if(a->type == D_FILE) |
| 1600 put(nil, a->asym->name, 'z', a->aoffset, 0, 0, 0
); |
| 1601 else |
| 1602 if(a->type == D_FILE1) |
| 1603 put(nil, a->asym->name, 'Z', a->aoffset, 0, 0, 0
); |
| 1604 |
| 1605 put(s, s->name, 'T', s->value, s->size, s->version, s->gotype); |
| 1606 |
| 1607 /* frame, auto and param after */ |
| 1608 put(nil, ".frame", 'm', s->text->to.offset+PtrSize, 0, 0, 0); |
| 1609 |
| 1610 for(a=s->autom; a; a=a->link) |
| 1611 if(a->type == D_AUTO) |
| 1612 put(nil, a->asym->name, 'a', -a->aoffset, 0, 0,
a->gotype); |
| 1613 else |
| 1614 if(a->type == D_PARAM) |
| 1615 put(nil, a->asym->name, 'p', a->aoffset, 0, 0, a
->gotype); |
| 1616 } |
| 1617 if(debug['v'] || debug['n']) |
| 1618 Bprint(&bso, "symsize = %ud\n", symsize); |
| 1619 Bflush(&bso); |
| 1620 } |
LEFT | RIGHT |