github.com/bir3/gocompiler@v0.9.2202/src/cmd/asm/main.go (about) 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 asm 6 7 import ( 8 "bufio" 9 "github.com/bir3/gocompiler/src/cmd/asm/flag" 10 "fmt" 11 "github.com/bir3/gocompiler/src/internal/buildcfg" 12 "log" 13 "os" 14 15 "github.com/bir3/gocompiler/src/cmd/asm/internal/arch" 16 "github.com/bir3/gocompiler/src/cmd/asm/internal/asm" 17 "github.com/bir3/gocompiler/src/cmd/asm/internal/flags" 18 "github.com/bir3/gocompiler/src/cmd/asm/internal/lex" 19 20 "github.com/bir3/gocompiler/src/cmd/internal/bio" 21 "github.com/bir3/gocompiler/src/cmd/internal/obj" 22 "github.com/bir3/gocompiler/src/cmd/internal/objabi" 23 ) 24 25 func Main() { 26 log.SetFlags(0) 27 log.SetPrefix("asm: ") 28 29 buildcfg.Check() 30 GOARCH := buildcfg.GOARCH 31 32 flags.Parse() 33 34 architecture := arch.Set(GOARCH, *flags.Shared || *flags.Dynlink) 35 if architecture == nil { 36 log.Fatalf("unrecognized architecture %s", GOARCH) 37 } 38 ctxt := obj.Linknew(architecture.LinkArch) 39 ctxt.Debugasm = flags.PrintOut 40 ctxt.Debugvlog = flags.DebugV 41 ctxt.Flag_dynlink = *flags.Dynlink 42 ctxt.Flag_linkshared = *flags.Linkshared 43 ctxt.Flag_shared = *flags.Shared || *flags.Dynlink 44 ctxt.Flag_maymorestack = flags.DebugFlags.MayMoreStack 45 ctxt.Debugpcln = flags.DebugFlags.PCTab 46 ctxt.IsAsm = true 47 ctxt.Pkgpath = *flags.Importpath 48 switch *flags.Spectre { 49 default: 50 log.Printf("unknown setting -spectre=%s", *flags.Spectre) 51 os.Exit(2) 52 case "": 53 // nothing 54 case "index": 55 // known to compiler; ignore here so people can use 56 // the same list with -gcflags=-spectre=LIST and -asmflags=-spectrre=LIST 57 case "all", "ret": 58 ctxt.Retpoline = true 59 } 60 61 ctxt.Bso = bufio.NewWriter(os.Stdout) 62 defer ctxt.Bso.Flush() 63 64 architecture.Init(ctxt) 65 66 // Create object file, write header. 67 buf, err := bio.Create(*flags.OutputFile) 68 if err != nil { 69 log.Fatal(err) 70 } 71 defer buf.Close() 72 73 if !*flags.SymABIs { 74 buf.WriteString(objabi.HeaderString()) 75 fmt.Fprintf(buf, "!\n") 76 } 77 78 // Set macros for GOEXPERIMENTs so we can easily switch 79 // runtime assembly code based on them. 80 if objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI { 81 for _, exp := range buildcfg.Experiment.Enabled() { 82 flags.D = append(flags.D, "GOEXPERIMENT_"+exp) 83 } 84 } 85 86 var ok, diag bool 87 var failedFile string 88 for _, f := range flag.Args() { 89 lexer := lex.NewLexer(f) 90 parser := asm.NewParser(ctxt, architecture, lexer) 91 ctxt.DiagFunc = func(format string, args ...interface{}) { 92 diag = true 93 log.Printf(format, args...) 94 } 95 if *flags.SymABIs { 96 ok = parser.ParseSymABIs(buf) 97 } else { 98 pList := new(obj.Plist) 99 pList.Firstpc, ok = parser.Parse() 100 // reports errors to parser.Errorf 101 if ok { 102 obj.Flushplist(ctxt, pList, nil) 103 } 104 } 105 if !ok { 106 failedFile = f 107 break 108 } 109 } 110 if ok && !*flags.SymABIs { 111 ctxt.NumberSyms() 112 obj.WriteObjFile(ctxt, buf) 113 } 114 if !ok || diag { 115 if failedFile != "" { 116 log.Printf("assembly of %s failed", failedFile) 117 } else { 118 log.Print("assembly failed") 119 } 120 buf.Close() 121 os.Remove(*flags.OutputFile) 122 os.Exit(1) 123 } 124 }