diff options
| author | Austin Clements <austin@google.com> | 2018-10-26 13:53:02 -0400 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2018-11-12 20:46:48 +0000 |
| commit | c5718b6b261a66aa47312037f17281d3d810c98c (patch) | |
| tree | ee975d089cb20dc038be7e1a4e68030a80615fe9 /src/cmd/internal/goobj/read.go | |
| parent | 07544c7e80a7559973930befca8c8744f43df3ce (diff) | |
| download | go-git-c5718b6b261a66aa47312037f17281d3d810c98c.tar.gz | |
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>
Diffstat (limited to 'src/cmd/internal/goobj/read.go')
| -rw-r--r-- | src/cmd/internal/goobj/read.go | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/src/cmd/internal/goobj/read.go b/src/cmd/internal/goobj/read.go index 2d618eefa5..2081098ca8 100644 --- a/src/cmd/internal/goobj/read.go +++ b/src/cmd/internal/goobj/read.go @@ -288,18 +288,31 @@ func (r *objReader) readSymID() SymID { } func (r *objReader) readRef() { - name, vers := r.readString(), r.readInt() + name, abiOrStatic := r.readString(), r.readInt() // In a symbol name in an object file, "". denotes the // prefix for the package in which the object file has been found. // Expand it. name = strings.ReplaceAll(name, `"".`, r.pkgprefix) - // An individual object file only records version 0 (extern) or 1 (static). - // To make static symbols unique across all files being read, we - // replace version 1 with the version corresponding to the current - // file number. The number is incremented on each call to parseObject. - if vers != 0 { + // The ABI field records either the ABI or -1 for static symbols. + // + // To distinguish different static symbols with the same name, + // we use the symbol "version". Version 0 corresponds to + // global symbols, and each file has a unique version > 0 for + // all of its static symbols. The version is incremented on + // each call to parseObject. + // + // For global symbols, we currently ignore the ABI. + // + // TODO(austin): Record the ABI in SymID. Since this is a + // public API, we'll have to keep Version as 0 and record the + // ABI in a new field (which differs from how the linker does + // this, but that's okay). Show the ABI in things like + // objdump. + var vers int64 + if abiOrStatic == -1 { + // Static symbol vers = r.p.MaxVersion } r.p.SymRefs = append(r.p.SymRefs, SymID{name, vers}) @@ -487,7 +500,7 @@ func (r *objReader) parseObject(prefix []byte) error { // TODO: extract OS + build ID if/when we need it r.readFull(r.tmp[:8]) - if !bytes.Equal(r.tmp[:8], []byte("\x00\x00go19ld")) { + if !bytes.Equal(r.tmp[:8], []byte("\x00go112ld")) { return r.error(errCorruptObject) } @@ -602,7 +615,7 @@ func (r *objReader) parseObject(prefix []byte) error { } r.readFull(r.tmp[:7]) - if !bytes.Equal(r.tmp[:7], []byte("\xffgo19ld")) { + if !bytes.Equal(r.tmp[:7], []byte("go112ld")) { return r.error(errCorruptObject) } |
