Home | History | Annotate | Download | only in asm
      1 // Copyright 2014 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package main
      6 
      7 import (
      8 	"bufio"
      9 	"flag"
     10 	"fmt"
     11 	"log"
     12 	"os"
     13 
     14 	"cmd/asm/internal/arch"
     15 	"cmd/asm/internal/asm"
     16 	"cmd/asm/internal/flags"
     17 	"cmd/asm/internal/lex"
     18 
     19 	"cmd/internal/bio"
     20 	"cmd/internal/obj"
     21 )
     22 
     23 func main() {
     24 	log.SetFlags(0)
     25 	log.SetPrefix("asm: ")
     26 
     27 	GOARCH := obj.GOARCH
     28 
     29 	architecture := arch.Set(GOARCH)
     30 	if architecture == nil {
     31 		log.Fatalf("unrecognized architecture %s", GOARCH)
     32 	}
     33 
     34 	flags.Parse()
     35 
     36 	ctxt := obj.Linknew(architecture.LinkArch)
     37 	if *flags.PrintOut {
     38 		ctxt.Debugasm = 1
     39 	}
     40 	ctxt.LineHist.TrimPathPrefix = *flags.TrimPath
     41 	ctxt.Flag_dynlink = *flags.Dynlink
     42 	ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
     43 	ctxt.Bso = bufio.NewWriter(os.Stdout)
     44 	defer ctxt.Bso.Flush()
     45 
     46 	// Create object file, write header.
     47 	out, err := os.Create(*flags.OutputFile)
     48 	if err != nil {
     49 		log.Fatal(err)
     50 	}
     51 	defer bio.MustClose(out)
     52 	buf := bufio.NewWriter(bio.MustWriter(out))
     53 
     54 	fmt.Fprintf(buf, "go object %s %s %s\n", obj.GOOS, obj.GOARCH, obj.Version)
     55 	fmt.Fprintf(buf, "!\n")
     56 
     57 	var ok, diag bool
     58 	var failedFile string
     59 	for _, f := range flag.Args() {
     60 		lexer := lex.NewLexer(f, ctxt)
     61 		parser := asm.NewParser(ctxt, architecture, lexer)
     62 		ctxt.DiagFunc = func(format string, args ...interface{}) {
     63 			diag = true
     64 			log.Printf(format, args...)
     65 		}
     66 		pList := obj.Linknewplist(ctxt)
     67 		pList.Firstpc, ok = parser.Parse()
     68 		if !ok {
     69 			failedFile = f
     70 			break
     71 		}
     72 	}
     73 	if ok {
     74 		// reports errors to parser.Errorf
     75 		obj.Writeobjdirect(ctxt, buf)
     76 	}
     77 	if !ok || diag {
     78 		if failedFile != "" {
     79 			log.Printf("assembly of %s failed", failedFile)
     80 		} else {
     81 			log.Print("assembly failed")
     82 		}
     83 		out.Close()
     84 		os.Remove(*flags.OutputFile)
     85 		os.Exit(1)
     86 	}
     87 	buf.Flush()
     88 }
     89