2015-01-22 10:48:33 -08:00
|
|
|
// 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 (
|
2016-04-08 19:30:41 +10:00
|
|
|
"bufio"
|
2015-01-22 10:48:33 -08:00
|
|
|
"flag"
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
"os"
|
|
|
|
|
|
|
|
|
|
"cmd/asm/internal/arch"
|
|
|
|
|
"cmd/asm/internal/asm"
|
|
|
|
|
"cmd/asm/internal/flags"
|
|
|
|
|
"cmd/asm/internal/lex"
|
|
|
|
|
|
2016-04-06 21:45:29 -07:00
|
|
|
"cmd/internal/bio"
|
2015-01-22 10:48:33 -08:00
|
|
|
"cmd/internal/obj"
|
2017-04-18 12:53:25 -07:00
|
|
|
"cmd/internal/objabi"
|
2015-01-22 10:48:33 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
log.SetFlags(0)
|
|
|
|
|
log.SetPrefix("asm: ")
|
|
|
|
|
|
2017-04-18 12:53:25 -07:00
|
|
|
GOARCH := objabi.GOARCH
|
2015-01-22 10:48:33 -08:00
|
|
|
|
|
|
|
|
architecture := arch.Set(GOARCH)
|
|
|
|
|
if architecture == nil {
|
2016-02-19 16:02:54 -08:00
|
|
|
log.Fatalf("unrecognized architecture %s", GOARCH)
|
2015-01-22 10:48:33 -08:00
|
|
|
}
|
|
|
|
|
|
2015-05-21 13:28:17 -04:00
|
|
|
flags.Parse()
|
2015-01-22 10:48:33 -08:00
|
|
|
|
|
|
|
|
ctxt := obj.Linknew(architecture.LinkArch)
|
|
|
|
|
if *flags.PrintOut {
|
2018-12-07 10:00:36 -08:00
|
|
|
ctxt.Debugasm = 1
|
2015-01-22 10:48:33 -08:00
|
|
|
}
|
2015-03-30 00:49:25 +00:00
|
|
|
ctxt.Flag_dynlink = *flags.Dynlink
|
2016-04-13 18:41:59 -07:00
|
|
|
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink
|
2016-04-08 19:30:41 +10:00
|
|
|
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
2015-05-01 11:51:47 +10:00
|
|
|
defer ctxt.Bso.Flush()
|
2016-04-08 19:30:41 +10:00
|
|
|
|
2017-04-06 13:42:31 -07:00
|
|
|
architecture.Init(ctxt)
|
|
|
|
|
|
2016-04-08 19:30:41 +10:00
|
|
|
// Create object file, write header.
|
2019-09-11 16:11:31 -04:00
|
|
|
buf, err := bio.Create(*flags.OutputFile)
|
2016-04-08 19:30:41 +10:00
|
|
|
if err != nil {
|
|
|
|
|
log.Fatal(err)
|
|
|
|
|
}
|
2019-09-11 16:11:31 -04:00
|
|
|
defer buf.Close()
|
2016-04-12 17:58:46 -07:00
|
|
|
|
2018-10-19 16:24:59 -04:00
|
|
|
if !*flags.SymABIs {
|
|
|
|
|
fmt.Fprintf(buf, "go object %s %s %s\n", objabi.GOOS, objabi.GOARCH, objabi.Version)
|
|
|
|
|
fmt.Fprintf(buf, "!\n")
|
|
|
|
|
}
|
2015-01-22 10:48:33 -08:00
|
|
|
|
2016-05-18 13:27:11 -07:00
|
|
|
var ok, diag bool
|
|
|
|
|
var failedFile string
|
|
|
|
|
for _, f := range flag.Args() {
|
2016-12-09 17:15:05 -08:00
|
|
|
lexer := lex.NewLexer(f)
|
2016-05-18 13:27:11 -07:00
|
|
|
parser := asm.NewParser(ctxt, architecture, lexer)
|
|
|
|
|
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
|
|
|
|
diag = true
|
|
|
|
|
log.Printf(format, args...)
|
|
|
|
|
}
|
2018-10-19 16:24:59 -04:00
|
|
|
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, "")
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-05-18 13:27:11 -07:00
|
|
|
if !ok {
|
|
|
|
|
failedFile = f
|
|
|
|
|
break
|
|
|
|
|
}
|
2016-01-21 22:48:29 -05:00
|
|
|
}
|
2018-10-19 16:24:59 -04:00
|
|
|
if ok && !*flags.SymABIs {
|
[dev.link] cmd/compile, cmd/asm: assign index to symbols
We are planning to use indices for symbol references, instead of
symbol names. Here we assign indices to symbols defined in the
package being compiled, and propagate the indices to the
dependent packages in the export data.
A symbol is referenced by a tuple, (package index, symbol index).
Normally, for a given symbol, this index is unique, and the
symbol index is globally consistent (but with exceptions, see
below). The package index is local to a compilation. For example,
when compiling the fmt package, fmt.Println gets assigned index
25, then all packages that reference fmt.Println will refer it
as (X, 25) with some X. X is the index for the fmt package, which
may differ in different compilations.
There are some symbols that do not have clear package affiliation,
such as dupOK symbols and linknamed symbols. We cannot give them
globally consistent indices. We categorize them as non-package
symbols, assign them with package index 1 and a symbol index that
is only meaningful locally.
Currently nothing will consume the indices.
All this is behind a flag, -newobj. The flag needs to be set for
all builds (-gcflags=all=-newobj -asmflags=all=-newobj), or none.
Change-Id: I18e489c531e9a9fbc668519af92c6116b7308cab
Reviewed-on: https://go-review.googlesource.com/c/go/+/196029
Reviewed-by: Than McIntosh <thanm@google.com>
2019-09-11 16:17:01 -04:00
|
|
|
ctxt.NumberSyms(true)
|
cmd/internal/obj: write package path at compile time if possible
Currently, when the compiler emits a symbol name in the object
file, it uses "". for the package path of the package being
compiled. This is then expanded in the linker to the actual
package path.
With CL 173938, it does not need an allocation if the symbol name
does not need expansion. In many cases, the compiler actually
knows the package path (through the -p flag), so we could just
write it out in compile time, without fixing it up in the linker.
This reduces allocations in the linker.
In case that the package path is not known (compiler's -p flag is
missing, or the object file is generated by the assembler), the
linker still does the expansion.
This reduces ~100MB allocations (~10% inuse_space) in linking
k8s.io/kubernetes/cmd/kube-apiserver on Linux/AMD64.
Also makes the linker a little faster: linking cmd/go on
Linux/AMD64:
Real 1.13 ± 1% 1.11 ± 1% -2.13% (p=0.000 n=10+10)
User 1.17 ± 3% 1.14 ± 5% -3.14% (p=0.003 n=10+10)
Sys 0.34 ±15% 0.34 ±15% ~ (p=0.986 n=10+10)
The caveat is that the object files get slightly bigger. On
Linux/AMD64, runtime.a gets 2.1% bigger, cmd/compile/internal/ssa
(which has a longer import path) gets 2.8% bigger.
This reveals that when building an unnamed plugin (e.g.
go build -buildmode=plugin x.go), the go command passes different
package paths to the compiler and to the linker. Before this CL
there seems nothing obviously broken, but given that the compiler
already emits the package's import path in various places (e.g.
debug info), I guess it is possible that this leads to some
unexpected behavior. Now that the compiler writes the package
path in more places, this disagreement actually leads to
unresolved symbols. Adjust the go command to use the same package
path for both compiling and linking.
Change-Id: I19f08981f51db577871c906e08d9e0fd588a2dd8
Reviewed-on: https://go-review.googlesource.com/c/go/+/174657
Reviewed-by: Austin Clements <austin@google.com>
2019-04-30 20:47:48 -04:00
|
|
|
obj.WriteObjFile(ctxt, buf, "")
|
2016-01-21 22:48:29 -05:00
|
|
|
}
|
|
|
|
|
if !ok || diag {
|
2016-05-18 13:27:11 -07:00
|
|
|
if failedFile != "" {
|
|
|
|
|
log.Printf("assembly of %s failed", failedFile)
|
|
|
|
|
} else {
|
|
|
|
|
log.Print("assembly failed")
|
|
|
|
|
}
|
2019-09-11 16:11:31 -04:00
|
|
|
buf.Close()
|
2015-04-08 11:24:48 -07:00
|
|
|
os.Remove(*flags.OutputFile)
|
2015-01-22 10:48:33 -08:00
|
|
|
os.Exit(1)
|
|
|
|
|
}
|
|
|
|
|
}
|