summaryrefslogtreecommitdiffstats
path: root/src/cmd/asm/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/asm/main.go')
-rw-r--r--src/cmd/asm/main.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/src/cmd/asm/main.go b/src/cmd/asm/main.go
new file mode 100644
index 0000000..ba69195
--- /dev/null
+++ b/src/cmd/asm/main.go
@@ -0,0 +1,124 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bufio"
+ "flag"
+ "fmt"
+ "internal/buildcfg"
+ "log"
+ "os"
+
+ "cmd/asm/internal/arch"
+ "cmd/asm/internal/asm"
+ "cmd/asm/internal/flags"
+ "cmd/asm/internal/lex"
+
+ "cmd/internal/bio"
+ "cmd/internal/obj"
+ "cmd/internal/objabi"
+)
+
+func main() {
+ log.SetFlags(0)
+ log.SetPrefix("asm: ")
+
+ buildcfg.Check()
+ GOARCH := buildcfg.GOARCH
+
+ flags.Parse()
+
+ architecture := arch.Set(GOARCH, *flags.Shared || *flags.Dynlink)
+ if architecture == nil {
+ log.Fatalf("unrecognized architecture %s", GOARCH)
+ }
+ ctxt := obj.Linknew(architecture.LinkArch)
+ ctxt.Debugasm = flags.PrintOut
+ ctxt.Debugvlog = flags.DebugV
+ ctxt.Flag_dynlink = *flags.Dynlink
+ ctxt.Flag_linkshared = *flags.Linkshared
+ ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
+ ctxt.Flag_maymorestack = flags.DebugFlags.MayMoreStack
+ ctxt.Debugpcln = flags.DebugFlags.PCTab
+ ctxt.IsAsm = true
+ ctxt.Pkgpath = *flags.Importpath
+ switch *flags.Spectre {
+ default:
+ log.Printf("unknown setting -spectre=%s", *flags.Spectre)
+ os.Exit(2)
+ case "":
+ // nothing
+ case "index":
+ // known to compiler; ignore here so people can use
+ // the same list with -gcflags=-spectre=LIST and -asmflags=-spectrre=LIST
+ case "all", "ret":
+ ctxt.Retpoline = true
+ }
+
+ ctxt.Bso = bufio.NewWriter(os.Stdout)
+ defer ctxt.Bso.Flush()
+
+ architecture.Init(ctxt)
+
+ // Create object file, write header.
+ buf, err := bio.Create(*flags.OutputFile)
+ if err != nil {
+ log.Fatal(err)
+ }
+ defer buf.Close()
+
+ if !*flags.SymABIs {
+ buf.WriteString(objabi.HeaderString())
+ fmt.Fprintf(buf, "!\n")
+ }
+
+ // Set macros for GOEXPERIMENTs so we can easily switch
+ // runtime assembly code based on them.
+ if objabi.LookupPkgSpecial(ctxt.Pkgpath).AllowAsmABI {
+ for _, exp := range buildcfg.Experiment.Enabled() {
+ flags.D = append(flags.D, "GOEXPERIMENT_"+exp)
+ }
+ }
+
+ var ok, diag bool
+ var failedFile string
+ for _, f := range flag.Args() {
+ lexer := lex.NewLexer(f)
+ parser := asm.NewParser(ctxt, architecture, lexer)
+ ctxt.DiagFunc = func(format string, args ...interface{}) {
+ diag = true
+ log.Printf(format, args...)
+ }
+ if *flags.SymABIs {
+ ok = parser.ParseSymABIs(buf)
+ } else {
+ pList := new(obj.Plist)
+ pList.Firstpc, ok = parser.Parse()
+ // reports errors to parser.Errorf
+ if ok {
+ obj.Flushplist(ctxt, pList, nil)
+ }
+ }
+ if !ok {
+ failedFile = f
+ break
+ }
+ }
+ if ok && !*flags.SymABIs {
+ ctxt.NumberSyms()
+ obj.WriteObjFile(ctxt, buf)
+ }
+ if !ok || diag {
+ if failedFile != "" {
+ log.Printf("assembly of %s failed", failedFile)
+ } else {
+ log.Print("assembly failed")
+ }
+ buf.Close()
+ os.Remove(*flags.OutputFile)
+ os.Exit(1)
+ }
+}