func assemble(file string) int { if outfile == "" { outfile = strings.TrimSuffix(filepath.Base(file), ".s") + "." + string(Thechar) } of, err := os.Create(outfile) if err != nil { Yyerror("%ca: cannot create %s", Thechar, outfile) errorexit() } obuf = *obj.Binitw(of) fmt.Fprintf(&obuf, "go object %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion()) fmt.Fprintf(&obuf, "!\n") var i int for Pass = 1; Pass <= 2; Pass++ { pinit(file) for i = 0; i < len(Dlist); i++ { dodefine(Dlist[i]) } Yyparse() Cclean() if nerrors != 0 { return nerrors } } obj.Writeobjdirect(Ctxt, &obuf) obj.Bflush(&obuf) return 0 }
func errorexit() { obj.Bflush(&bstdout) if outfile != "" { os.Remove(outfile) } os.Exit(2) }
func Main() { // Allow GOARCH=Thestring or GOARCH=Thestringsuffix, // but not other values. p := obj.Getgoarch() if !strings.HasPrefix(p, Thestring) { log.Fatalf("cannot use %cc with GOARCH=%s", Thechar, p) } if p != Thestring { Thelinkarch = Arches[p] if Thelinkarch == nil { log.Fatalf("unknown arch %s", p) } } Ctxt = obj.Linknew(Thelinkarch) Ctxt.Diag = Yyerror Ctxt.Bso = &bstdout Ctxt.Enforce_data_order = 1 bstdout = *obj.Binitw(os.Stdout) debug = [256]int{} cinit() outfile = "" setinclude(".") flag.Var(flagFn(dodef), "D", "name[=value]: add #define") flag.Var(flagFn(setinclude), "I", "dir: add dir to include path") flag.Var((*count)(&debug['S']), "S", "print assembly and machine code") flag.Var((*count)(&debug['m']), "m", "debug preprocessor macros") flag.StringVar(&outfile, "o", "", "file: set output file") flag.StringVar(&Ctxt.LineHist.TrimPathPrefix, "trimpath", "", "prefix: remove prefix from recorded source file paths") flag.Parse() Ctxt.Debugasm = int32(debug['S']) if flag.NArg() < 1 { usage() } if flag.NArg() > 1 { fmt.Printf("can't assemble multiple files\n") errorexit() } if assemble(flag.Arg(0)) != 0 { errorexit() } obj.Bflush(&bstdout) if nerrors > 0 { errorexit() } }
func dumpobj() { var err error bout, err = obj.Bopenw(outfile) if err != nil { Flusherrors() fmt.Printf("can't create %s: %v\n", outfile, err) errorexit() } startobj := int64(0) var arhdr [ArhdrSize]byte if writearchive != 0 { obj.Bwritestring(bout, "!<arch>\n") arhdr = [ArhdrSize]byte{} obj.Bwrite(bout, arhdr[:]) startobj = obj.Boffset(bout) } fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring()) dumpexport() if writearchive != 0 { obj.Bflush(bout) size := obj.Boffset(bout) - startobj if size&1 != 0 { obj.Bputc(bout, 0) } obj.Bseek(bout, startobj-ArhdrSize, 0) formathdr(arhdr[:], "__.PKGDEF", size) obj.Bwrite(bout, arhdr[:]) obj.Bflush(bout) obj.Bseek(bout, startobj+size+(size&1), 0) arhdr = [ArhdrSize]byte{} obj.Bwrite(bout, arhdr[:]) startobj = obj.Boffset(bout) fmt.Fprintf(bout, "go object %s %s %s %s\n", obj.Getgoos(), obj.Getgoarch(), obj.Getgoversion(), obj.Expstring()) } if pragcgobuf != "" { if writearchive != 0 { // write empty export section; must be before cgo section fmt.Fprintf(bout, "\n$$\n\n$$\n\n") } fmt.Fprintf(bout, "\n$$ // cgo\n") fmt.Fprintf(bout, "%s\n$$\n\n", pragcgobuf) } fmt.Fprintf(bout, "\n!\n") var externs *NodeList 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, int32(zerosize), obj.DUPOK|obj.RODATA) dumpdata() obj.Writeobjdirect(Ctxt, bout) if writearchive != 0 { obj.Bflush(bout) size := obj.Boffset(bout) - startobj if size&1 != 0 { obj.Bputc(bout, 0) } obj.Bseek(bout, startobj-ArhdrSize, 0) name := fmt.Sprintf("_go_.%c", Thearch.Thechar) formathdr(arhdr[:], name, size) obj.Bwrite(bout, arhdr[:]) } obj.Bterm(bout) }