github.com/bir3/gocompiler@v0.3.205/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  
    39  	ctxt := obj.Linknew(architecture.LinkArch)
    40  	ctxt.Debugasm = flags.PrintOut
    41  	ctxt.Debugvlog = flags.DebugV
    42  	ctxt.Flag_dynlink = *flags.Dynlink
    43  	ctxt.Flag_linkshared = *flags.Linkshared
    44  	ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
    45  	ctxt.Flag_maymorestack = flags.DebugFlags.MayMoreStack
    46  	ctxt.Debugpcln = flags.DebugFlags.PCTab
    47  	ctxt.IsAsm = true
    48  	ctxt.Pkgpath = *flags.Importpath
    49  	switch *flags.Spectre {
    50  	default:
    51  		log.Printf("unknown setting -spectre=%s", *flags.Spectre)
    52  		os.Exit(2)
    53  	case "":
    54  		// nothing
    55  	case "index":
    56  		// known to compiler; ignore here so people can use
    57  		// the same list with -gcflags=-spectre=LIST and -asmflags=-spectrre=LIST
    58  	case "all", "ret":
    59  		ctxt.Retpoline = true
    60  	}
    61  
    62  	ctxt.Bso = bufio.NewWriter(os.Stdout)
    63  	defer ctxt.Bso.Flush()
    64  
    65  	architecture.Init(ctxt)
    66  
    67  	// Create object file, write header.
    68  	buf, err := bio.Create(*flags.OutputFile)
    69  	if err != nil {
    70  		log.Fatal(err)
    71  	}
    72  	defer buf.Close()
    73  
    74  	if !*flags.SymABIs {
    75  		buf.WriteString(objabi.HeaderString())
    76  		fmt.Fprintf(buf, "!\n")
    77  	}
    78  
    79  	var ok, diag bool
    80  	var failedFile string
    81  	for _, f := range flag.Args() {
    82  		lexer := lex.NewLexer(f)
    83  		parser := asm.NewParser(ctxt, architecture, lexer,
    84  			*flags.CompilingRuntime)
    85  		ctxt.DiagFunc = func(format string, args ...interface{}) {
    86  			diag = true
    87  			log.Printf(format, args...)
    88  		}
    89  		if *flags.SymABIs {
    90  			ok = parser.ParseSymABIs(buf)
    91  		} else {
    92  			pList := new(obj.Plist)
    93  			pList.Firstpc, ok = parser.Parse()
    94  			// reports errors to parser.Errorf
    95  			if ok {
    96  				obj.Flushplist(ctxt, pList, nil, *flags.Importpath)
    97  			}
    98  		}
    99  		if !ok {
   100  			failedFile = f
   101  			break
   102  		}
   103  	}
   104  	if ok && !*flags.SymABIs {
   105  		ctxt.NumberSyms()
   106  		obj.WriteObjFile(ctxt, buf)
   107  	}
   108  	if !ok || diag {
   109  		if failedFile != "" {
   110  			log.Printf("assembly of %s failed", failedFile)
   111  		} else {
   112  			log.Print("assembly failed")
   113  		}
   114  		buf.Close()
   115  		os.Remove(*flags.OutputFile)
   116  		os.Exit(1)
   117  	}
   118  }