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