mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile, cmd/link: separate stable and internal ABIs
This implements compiler and linker support for separating the function calling ABI into two ABIs: a stable and an internal ABI. At the moment, the two ABIs are identical, but we'll be able to evolve the internal ABI without breaking existing assembly code that depends on the stable ABI for calling to and from Go. The Go compiler generates internal ABI symbols for all Go functions. It uses the symabis information produced by the assembler to create ABI wrappers whenever it encounters a body-less Go function that's defined in assembly or a Go function that's referenced from assembly. Since the two ABIs are currently identical, for the moment this is implemented using "ABI alias" symbols, which are just forwarding references to the native ABI symbol for a function. This way there's no actual code involved in the ABI wrapper, which is good because we're not deriving any benefit from it right now. Once the ABIs diverge, we can eliminate ABI aliases. The linker represents these different ABIs internally as different versions of the same symbol. This way, the linker keeps us honest, since every symbol definition and reference also specifies its version. The linker is responsible for resolving ABI aliases. Fixes #27539. Change-Id: I197c52ec9f8fc435db8f7a4259029b20f6d65e95 Reviewed-on: https://go-review.googlesource.com/c/147160 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
1794ee6829
commit
685aca45dc
20 changed files with 194 additions and 32 deletions
|
|
@ -187,7 +187,13 @@ func (pp *Progs) settext(fn *Node) {
|
|||
ptxt.From.Sym = fn.Func.lsym
|
||||
}
|
||||
|
||||
func (f *Func) initLSym() {
|
||||
// initLSym defines f's obj.LSym and initializes it based on the
|
||||
// properties of f. This includes setting the symbol flags and ABI and
|
||||
// creating and initializing related DWARF symbols.
|
||||
//
|
||||
// initLSym must be called exactly once per function and must be
|
||||
// called for both functions with bodies and functions without bodies.
|
||||
func (f *Func) initLSym(hasBody bool) {
|
||||
if f.lsym != nil {
|
||||
Fatalf("Func.initLSym called twice")
|
||||
}
|
||||
|
|
@ -197,6 +203,61 @@ func (f *Func) initLSym() {
|
|||
if f.Pragma&Systemstack != 0 {
|
||||
f.lsym.Set(obj.AttrCFunc, true)
|
||||
}
|
||||
|
||||
var aliasABI obj.ABI
|
||||
needABIAlias := false
|
||||
if abi, ok := symabiDefs[f.lsym.Name]; ok && abi == obj.ABI0 {
|
||||
// Symbol is defined as ABI0. Create an
|
||||
// Internal -> ABI0 wrapper.
|
||||
f.lsym.SetABI(obj.ABI0)
|
||||
needABIAlias, aliasABI = true, obj.ABIInternal
|
||||
} else {
|
||||
// No ABI override. Check that the symbol is
|
||||
// using the expected ABI.
|
||||
want := obj.ABIInternal
|
||||
if f.lsym.ABI() != want {
|
||||
Fatalf("function symbol %s has the wrong ABI %v, expected %v", f.lsym, f.lsym.ABI(), want)
|
||||
}
|
||||
}
|
||||
|
||||
if abi, ok := symabiRefs[f.lsym.Name]; ok && abi == obj.ABI0 {
|
||||
// Symbol is referenced as ABI0. Create an
|
||||
// ABI0 -> Internal wrapper if necessary.
|
||||
if f.lsym.ABI() != obj.ABI0 {
|
||||
needABIAlias, aliasABI = true, obj.ABI0
|
||||
}
|
||||
}
|
||||
|
||||
if !needABIAlias && allABIs {
|
||||
// The compiler was asked to produce ABI
|
||||
// wrappers for everything.
|
||||
switch f.lsym.ABI() {
|
||||
case obj.ABI0:
|
||||
needABIAlias, aliasABI = true, obj.ABIInternal
|
||||
case obj.ABIInternal:
|
||||
needABIAlias, aliasABI = true, obj.ABI0
|
||||
}
|
||||
}
|
||||
|
||||
if needABIAlias {
|
||||
// These LSyms have the same name as the
|
||||
// native function, so we create them directly
|
||||
// rather than looking them up. The uniqueness
|
||||
// of f.lsym ensures uniqueness of asym.
|
||||
asym := &obj.LSym{
|
||||
Name: f.lsym.Name,
|
||||
Type: objabi.SABIALIAS,
|
||||
R: []obj.Reloc{{Sym: f.lsym}}, // 0 size, so "informational"
|
||||
}
|
||||
asym.SetABI(aliasABI)
|
||||
asym.Set(obj.AttrDuplicateOK, true)
|
||||
Ctxt.ABIAliases = append(Ctxt.ABIAliases, asym)
|
||||
}
|
||||
}
|
||||
|
||||
if !hasBody {
|
||||
// For body-less functions, we only create the LSym.
|
||||
return
|
||||
}
|
||||
|
||||
var flag int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue