cmd/internal/obj, cmd/link: record ABIs and aliases in Go obj files

This repurposes the "version" field of a symbol reference in the Go
object file format to be an ABI field. Currently, this is just 0 or 1
depending on whether the symbol is static (the linker turns it into a
different internal version number), so it's already only tenuously a
symbol version. We change this to be -1 for static symbols and
otherwise by the ABI number.

This also adds a separate list of ABI alias symbols to be recorded in
the object file. The ABI aliases must be a separate list and not just
part of the symbol definitions because it's possible to have a symbol
defined in one package and the alias "defined" in a different package.
For example, this can happen if a symbol is defined in assembly in one
package and stubbed in a different package. The stub triggers the
generation of the ABI alias, but in a different package from the
definition.

For #27539.

Change-Id: I015c9fe54690c027de6ef77e22b5585976a01587
Reviewed-on: https://go-review.googlesource.com/c/147157
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:
Austin Clements 2018-10-26 13:53:02 -04:00
parent 07544c7e80
commit c5718b6b26
6 changed files with 96 additions and 26 deletions

View file

@ -13,6 +13,7 @@ import (
"bytes"
"cmd/internal/bio"
"cmd/internal/dwarf"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
@ -23,8 +24,8 @@ import (
)
const (
startmagic = "\x00\x00go19ld"
endmagic = "\xff\xffgo19ld"
startmagic = "\x00go112ld"
endmagic = "\xffgo112ld"
)
var emptyPkg = []byte(`"".`)
@ -382,17 +383,20 @@ func (r *objReader) readRef() {
log.Fatalf("readSym out of sync")
}
name := r.readSymName()
v := r.readInt()
if v != 0 && v != 1 {
log.Fatalf("invalid symbol version for %q: %d", name, v)
}
if v == 1 {
var v int
if abi := r.readInt(); abi == -1 {
// Static
v = r.localSymVersion
} else if abiver := sym.ABIToVersion(obj.ABI(abi)); abiver != -1 {
// Note that data symbols are "ABI0", which maps to version 0.
v = abiver
} else {
log.Fatalf("invalid symbol ABI for %q: %d", name, abi)
}
s := r.syms.Lookup(name, v)
r.refs = append(r.refs, s)
if s == nil || v != 0 {
if s == nil || v == r.localSymVersion {
return
}
if s.Name[0] == '$' && len(s.Name) > 5 && s.Type == 0 && len(s.P) == 0 {