int assemble(char *file) { char *ofile, *p; int i, of; ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(outfile){ p = utfrrune(outfile, '.'); if(p) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = utfrune(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } else outfile = "/dev/null"; } of = create(outfile, OWRITE, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(file); Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); if(nerrors) { cclean(); return nerrors; } Bprint(&obuf, "\n!\n"); pass = 2; outhist(); pinit(file); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); cclean(); return nerrors; }
void outcode(void) { int f; Biobuf b; f = open(outfile, OWRITE); if(f < 0) { diag(Z, "cannot open %s", outfile); return; } Binit(&b, f, OWRITE); Bprint(&b, "go object %s %s %s\n", getgoos(), getgoarch(), getgoversion()); if(pragcgobuf.to > pragcgobuf.start) { Bprint(&b, "\n"); Bprint(&b, "$$ // exports\n\n"); Bprint(&b, "$$ // local types\n\n"); Bprint(&b, "$$ // cgo\n"); Bprint(&b, "%s", fmtstrflush(&pragcgobuf)); Bprint(&b, "\n$$\n\n"); } Bprint(&b, "!\n"); linkwriteobj(ctxt, &b); Bterm(&b); close(f); lastp = P; }
void mywhatsys(void) { goroot = getgoroot(); goos = getgoos(); goarch = thestring; // ignore $GOARCH - we know who we are }
void dumpobj(void) { bout = Bopen(outfile, OWRITE); if(bout == nil) { flusherrors(); print("can't create %s: %r\n", outfile); errorexit(); } Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring()); Bprint(bout, " exports automatically generated from\n"); Bprint(bout, " %s in package \"%s\"\n", curio.infile, localpkg->name); dumpexport(); Bprint(bout, "\n!\n"); outhist(bout); dumpglobls(); dumptypestructs(); dumpdata(); dumpfuncs(); Bterm(bout); }
void dumpobj(void) { NodeList *externs, *tmp; bout = Bopen(outfile, OWRITE); if(bout == nil) { flusherrors(); print("can't create %s: %r\n", outfile); errorexit(); } Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring()); Bprint(bout, " exports automatically generated from\n"); Bprint(bout, " %s in package \"%s\"\n", curio.infile, localpkg->name); dumpexport(); Bprint(bout, "\n!\n"); outhist(bout); externs = nil; if(externdcl != nil) externs = externdcl->end; dumpglobls(); dumptypestructs(); // Dump extra globals. tmp = externdcl; if(externs != nil) externdcl = externs->next; dumpglobls(); externdcl = tmp; dumpdata(); dumpfuncs(); Bterm(bout); }
void dumpobj(void) { NodeList *externs, *tmp; char arhdr[ArhdrSize]; vlong startobj, size; Sym *zero; bout = Bopen(outfile, OWRITE); if(bout == nil) { flusherrors(); print("can't create %s: %r\n", outfile); errorexit(); } startobj = 0; if(writearchive) { Bwrite(bout, "!<arch>\n", 8); memset(arhdr, 0, sizeof arhdr); Bwrite(bout, arhdr, sizeof arhdr); startobj = Boffset(bout); } Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring()); dumpexport(); if(writearchive) { Bflush(bout); size = Boffset(bout) - startobj; if(size&1) Bputc(bout, 0); Bseek(bout, startobj - ArhdrSize, 0); formathdr(arhdr, "__.PKGDEF", size); Bwrite(bout, arhdr, ArhdrSize); Bflush(bout); Bseek(bout, startobj + size + (size&1), 0); memset(arhdr, 0, ArhdrSize); Bwrite(bout, arhdr, ArhdrSize); startobj = Boffset(bout); Bprint(bout, "go object %s %s %s %s\n", getgoos(), getgoarch(), getgoversion(), expstring()); } Bprint(bout, "\n!\n"); externs = nil; if(externdcl != nil) externs = externdcl->end; dumpglobls(); dumptypestructs(); // Dump extra globals. tmp = externdcl; if(externs != nil) externdcl = externs->next; dumpglobls(); externdcl = tmp; zero = pkglookup("zerovalue", runtimepkg); ggloblsym(zero, zerosize, 1, 1); dumpdata(); writeobj(ctxt, bout); if(writearchive) { Bflush(bout); size = Boffset(bout) - startobj; if(size&1) Bputc(bout, 0); Bseek(bout, startobj - ArhdrSize, 0); snprint(namebuf, sizeof namebuf, "_go_.%c", thechar); formathdr(arhdr, namebuf, size); Bwrite(bout, arhdr, ArhdrSize); } Bterm(bout); }
void outcode(void) { struct { Sym *sym; short type; } h[NSYM]; Prog *p; Sym *s; int f, sf, st, t, sym; Biobuf b; if(debug['S']) { for(p = firstp; p != P; p = p->link) if(p->as != ADATA && p->as != AGLOBL) pc--; for(p = firstp; p != P; p = p->link) { print("%P\n", p); if(p->as != ADATA && p->as != AGLOBL) pc++; } } f = open(outfile, OWRITE); if(f < 0) { diag(Z, "cannot open %s", outfile); return; } Binit(&b, f, OWRITE); Bprint(&b, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); if(pragcgobuf.to > pragcgobuf.start) { Bprint(&b, "\n"); Bprint(&b, "$$ // exports\n\n"); Bprint(&b, "$$ // local types\n\n"); Bprint(&b, "$$ // cgo\n"); Bprint(&b, "%s", fmtstrflush(&pragcgobuf)); Bprint(&b, "\n$$\n\n"); } Bprint(&b, "!\n"); outhist(&b); for(sym=0; sym<NSYM; sym++) { h[sym].sym = S; h[sym].type = 0; } sym = 1; for(p = firstp; p != P; p = p->link) { jackpot: sf = 0; s = p->from.sym; while(s != S) { sf = s->sym; if(sf < 0 || sf >= NSYM) sf = 0; t = p->from.type; if(t == D_ADDR) t = p->from.index; if(h[sf].type == t) if(h[sf].sym == s) break; s->sym = sym; zname(&b, s, t); h[sym].sym = s; h[sym].type = t; sf = sym; sym++; if(sym >= NSYM) sym = 1; break; } st = 0; s = p->to.sym; while(s != S) { st = s->sym; if(st < 0 || st >= NSYM) st = 0; t = p->to.type; if(t == D_ADDR) t = p->to.index; if(h[st].type == t) if(h[st].sym == s) break; s->sym = sym; zname(&b, s, t); h[sym].sym = s; h[sym].type = t; st = sym; sym++; if(sym >= NSYM) sym = 1; if(st == sf) goto jackpot; break; } BPUTLE2(&b, p->as); BPUTLE4(&b, p->lineno); zaddr(&b, &p->from, sf); zaddr(&b, &p->to, st); } Bterm(&b); close(f); firstp = P; lastp = P; }
Link* linknew(LinkArch *arch) { Link *ctxt; char *p; char buf[1024]; nuxiinit(); ctxt = emallocz(sizeof *ctxt); ctxt->arch = arch; ctxt->version = HistVersion; ctxt->goroot = getgoroot(); ctxt->goroot_final = getenv("GOROOT_FINAL"); if(ctxt->goroot_final != nil && ctxt->goroot_final[0] == '\0') ctxt->goroot_final = nil; p = getgoarch(); if(strcmp(p, arch->name) != 0) sysfatal("invalid goarch %s (want %s)", p, arch->name); if(getwd(buf, sizeof buf) == 0) strcpy(buf, "/???"); if(yy_isalpha(buf[0]) && buf[1] == ':') { // On Windows. ctxt->windows = 1; // Canonicalize path by converting \ to / (Windows accepts both). for(p=buf; *p; p++) if(*p == '\\') *p = '/'; } ctxt->pathname = strdup(buf); ctxt->headtype = headtype(getgoos()); if(ctxt->headtype < 0) sysfatal("unknown goos %s", getgoos()); // Record thread-local storage offset. // TODO(rsc): Move tlsoffset back into the linker. switch(ctxt->headtype) { default: sysfatal("unknown thread-local storage offset for %s", headstr(ctxt->headtype)); case Hplan9: ctxt->tlsoffset = -2*ctxt->arch->ptrsize; break; case Hwindows: break; case Hlinux: case Hfreebsd: case Hnetbsd: case Hopenbsd: case Hdragonfly: case Hsolaris: /* * ELF uses TLS offset negative from FS. * Translate 0(FS) and 8(FS) into -16(FS) and -8(FS). * Known to low-level assembly in package runtime and runtime/cgo. */ ctxt->tlsoffset = -2*ctxt->arch->ptrsize; break; case Hnacl: switch(ctxt->arch->thechar) { default: sysfatal("unknown thread-local storage offset for nacl/%s", ctxt->arch->name); case '6': ctxt->tlsoffset = 0; break; case '8': ctxt->tlsoffset = -8; break; } break; case Hdarwin: /* * OS X system constants - offset from 0(GS) to our TLS. * Explained in ../../pkg/runtime/cgo/gcc_darwin_*.c. */ switch(ctxt->arch->thechar) { default: sysfatal("unknown thread-local storage offset for darwin/%s", ctxt->arch->name); case '6': ctxt->tlsoffset = 0x8a0; break; case '8': ctxt->tlsoffset = 0x468; break; } break; } // On arm, record goarm. if(ctxt->arch->thechar == '5') { p = getgoarm(); if(p != nil) ctxt->goarm = atoi(p); else ctxt->goarm = 6; } return ctxt; }