mirror of
https://github.com/golang/go
synced 2024-11-12 07:40:23 -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:
parent
ba2e8a629b
commit
97e4010fd4
@ -247,6 +247,9 @@ func Main(archInit func(*Arch)) {
|
||||
flag.Int64Var(&memprofilerate, "memprofilerate", 0, "set runtime.MemProfileRate to `rate`")
|
||||
var goversion string
|
||||
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(&blockprofile, "blockprofile", "", "write block profile to `file`")
|
||||
flag.StringVar(&mutexprofile, "mutexprofile", "", "write mutex profile to `file`")
|
||||
@ -285,6 +288,10 @@ func Main(archInit func(*Arch)) {
|
||||
|
||||
checkLang()
|
||||
|
||||
if symabisPath != "" {
|
||||
readSymABIs(symabisPath, myimportpath)
|
||||
}
|
||||
|
||||
thearch.LinkArch.Init(Ctxt)
|
||||
|
||||
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() {
|
||||
nsavederrors += nerrors
|
||||
nerrors = 0
|
||||
|
16
src/cmd/internal/obj/abi_string.go
Normal file
16
src/cmd/internal/obj/abi_string.go
Normal 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]]
|
||||
}
|
@ -409,6 +409,28 @@ type FuncInfo struct {
|
||||
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.
|
||||
type Attribute int16
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user