1
0
mirror of https://github.com/golang/go synced 2024-11-13 18:40:22 -07:00

cmd/compile: accept and parse symabis

This doesn't yet do anything with this information.

For #27539.

Change-Id: Ia12c905812aa1ed425eedd6ab2f55ec75d81c0ce
Reviewed-on: https://go-review.googlesource.com/c/147099
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Austin Clements 2018-10-22 10:10:23 -04:00
parent ba2e8a629b
commit 97e4010fd4
3 changed files with 120 additions and 0 deletions

View File

@ -247,6 +247,9 @@ func Main(archInit func(*Arch)) {
flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`") flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
var goversion string var goversion string
flag.StringVar(&goversion, "goversion", "", "required version of the runtime") flag.StringVar(&goversion, "goversion", "", "required version of the runtime")
var symabisPath string
flag.StringVar(&symabisPath, "symabis", "", "read symbol ABIs from `file`")
flag.BoolVar(&allABIs, "allabis", false, "generate ABI wrappers for all symbols (for bootstrap)")
flag.StringVar(&traceprofile, "traceprofile", "", "write an execution trace to `file`") flag.StringVar(&traceprofile, "traceprofile", "", "write an execution trace to `file`")
flag.StringVar(&blockprofile, "blockprofile", "", "write block profile to `file`") flag.StringVar(&blockprofile, "blockprofile", "", "write block profile to `file`")
flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`") flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`")
@ -285,6 +288,10 @@ func Main(archInit func(*Arch)) {
checkLang() checkLang()
if symabisPath != "" {
readSymABIs(symabisPath, myimportpath)
}
thearch.LinkArch.Init(Ctxt) thearch.LinkArch.Init(Ctxt)
if outfile == "" { if outfile == "" {
@ -810,6 +817,81 @@ func readImportCfg(file string) {
} }
} }
// symabiDefs and symabiRefs record the defined and referenced ABIs of
// symbols required by non-Go code. These are keyed by link symbol
// name, where the local package prefix is always `"".`
var symabiDefs, symabiRefs map[string]obj.ABI
// allABIs indicates that all symbol definitions should have ABI
// wrappers. This is used during toolchain bootstrapping to avoid
// having to find cross-package references.
var allABIs bool
// readSymABIs reads a symabis file that specifies definitions and
// references of text symbols by ABI.
//
// The symabis format is a set of lines, where each line is a sequence
// of whitespace-separated fields. The first field is a verb and is
// either "def" for defining a symbol ABI or "ref" for referencing a
// symbol using an ABI. For both "def" and "ref", the second field is
// the symbol name and the third field is the ABI name, as one of the
// named cmd/internal/obj.ABI constants.
func readSymABIs(file, myimportpath string) {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("-symabis: %v", err)
}
symabiDefs = make(map[string]obj.ABI)
symabiRefs = make(map[string]obj.ABI)
localPrefix := ""
if myimportpath != "" {
// Symbols in this package may be written either as
// "".X or with the package's import path already in
// the symbol.
localPrefix = objabi.PathToPrefix(myimportpath) + "."
}
for lineNum, line := range strings.Split(string(data), "\n") {
lineNum++ // 1-based
line = strings.TrimSpace(line)
if line == "" || strings.HasPrefix(line, "#") {
continue
}
parts := strings.Fields(line)
switch parts[0] {
case "def", "ref":
// Parse line.
if len(parts) != 3 {
log.Fatalf(`%s:%d: invalid symabi: syntax is "%s sym abi"`, file, lineNum, parts[0])
}
sym, abi := parts[1], parts[2]
if abi != "ABI0" { // Only supported external ABI right now
log.Fatalf(`%s:%d: invalid symabi: unknown abi "%s"`, file, lineNum, abi)
}
// If the symbol is already prefixed with
// myimportpath, rewrite it to start with ""
// so it matches the compiler's internal
// symbol names.
if localPrefix != "" && strings.HasPrefix(sym, localPrefix) {
sym = `"".` + sym[len(localPrefix):]
}
// Record for later.
if parts[0] == "def" {
symabiDefs[sym] = obj.ABI0
} else {
symabiRefs[sym] = obj.ABI0
}
default:
log.Fatalf(`%s:%d: invalid symabi type "%s"`, file, lineNum, parts[0])
}
}
}
func saveerrors() { func saveerrors() {
nsavederrors += nerrors nsavederrors += nerrors
nerrors = 0 nerrors = 0

View File

@ -0,0 +1,16 @@
// Code generated by "stringer -type ABI"; DO NOT EDIT.
package obj
import "strconv"
const _ABI_name = "ABI0ABIInternalABICount"
var _ABI_index = [...]uint8{0, 4, 15, 23}
func (i ABI) String() string {
if i >= ABI(len(_ABI_index)-1) {
return "ABI(" + strconv.FormatInt(int64(i), 10) + ")"
}
return _ABI_name[_ABI_index[i]:_ABI_index[i+1]]
}

View File

@ -409,6 +409,28 @@ type FuncInfo struct {
StackObjects *LSym StackObjects *LSym
} }
//go:generate stringer -type ABI
// ABI is the calling convention of a text symbol.
type ABI uint8
const (
// ABI0 is the stable stack-based ABI. It's important that the
// value of this is "0": we can't distinguish between
// references to data and ABI0 text symbols in assembly code,
// and hence this doesn't distinguish between symbols without
// an ABI and text symbols with ABI0.
ABI0 ABI = iota
// ABIInternal is the internal ABI that may change between Go
// versions. All Go functions use the internal ABI and the
// compiler generates wrappers for calls to and from other
// ABIs.
ABIInternal
ABICount
)
// Attribute is a set of symbol attributes. // Attribute is a set of symbol attributes.
type Attribute int16 type Attribute int16