liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 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"
   "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: ")
 
   GOARCH := objabi.GOARCH
 
   architecture := arch.Set(GOARCH)
   if architecture == nil {
       log.Fatalf("unrecognized architecture %s", GOARCH)
   }
 
   flags.Parse()
 
   ctxt := obj.Linknew(architecture.LinkArch)
   if *flags.PrintOut {
       ctxt.Debugasm = 1
   }
   ctxt.Flag_dynlink = *flags.Dynlink
   ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
   ctxt.Bso = bufio.NewWriter(os.Stdout)
   defer ctxt.Bso.Flush()
 
   architecture.Init(ctxt)
 
   // Create object file, write header.
   out, err := os.Create(*flags.OutputFile)
   if err != nil {
       log.Fatal(err)
   }
   defer bio.MustClose(out)
   buf := bufio.NewWriter(bio.MustWriter(out))
 
   if !*flags.SymABIs {
       fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
       fmt.Fprintf(buf, "!\n")
   }
 
   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 {
       obj.WriteObjFile(ctxt, buf)
   }
   if !ok || diag {
       if failedFile != "" {
           log.Printf("assembly of %s failed", failedFile)
       } else {
           log.Print("assembly failed")
       }
       out.Close()
       os.Remove(*flags.OutputFile)
       os.Exit(1)
   }
   buf.Flush()
}