[dev.link] cmd/link: initial support for linker-materialized external symbols

Create loader infrastructure for constructing the payloads of external
symbols from scratch, as opposed to passing in a sym.Symbol object
containing the payload.

The general idea is that clients can use the loader to create new
external Sym's using loader.AddExtSym, and then can add
relocations/data to the new sym with symbol builder interfaces (to be
provided in an subsequent patch), as opposed to having to use
sym.Symbol.

This change preserves compatibility with the old way of doing things
(passing in sym.Symbol) via a new loader.InstallSym method. If a
client invokes this method for a specific Sym, then the loader keeps
track of this fact and uses the sym.Symbol as the backing store instead.

Also included is a small unit test for the new interfaces -- not clear
whether this really needs to be kept around long term... it was mainly
useful during initial bringup.

Change-Id: If8ab15df7b64636e56b317155dfe6d7cdfe23b71
Reviewed-on: https://go-review.googlesource.com/c/go/+/207606
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Than McIntosh 2019-12-11 13:39:39 -05:00
parent 664accc7be
commit 07914eda40
2 changed files with 254 additions and 32 deletions

View file

@ -0,0 +1,55 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package loader
import (
"cmd/link/internal/sym"
"testing"
)
// dummyAddSym adds the named symbol to the loader as if it had been
// read from a Go object file. Note that it allocates a global
// index without creating an associated object reader, so one can't
// do anything interesting with this symbol (such as look at its
// data or relocations).
func addDummyObjSym(t *testing.T, ldr *Loader, or *oReader, name string) Sym {
idx := ldr.max + 1
ldr.max++
if ok := ldr.AddSym(name, 0, idx, or, false, sym.SRODATA); !ok {
t.Errorf("AddrSym failed for '" + name + "'")
}
return idx
}
func TestAddMaterializedSymbol(t *testing.T) {
ldr := NewLoader(0)
dummyOreader := oReader{version: -1}
or := &dummyOreader
// Create some syms from a dummy object file symbol to get things going.
addDummyObjSym(t, ldr, or, "type.uint8")
addDummyObjSym(t, ldr, or, "mumble")
addDummyObjSym(t, ldr, or, "type.string")
// Create some external symbols.
es1 := ldr.AddExtSym("extnew1", 0)
if es1 == 0 {
t.Fatalf("AddExtSym failed for extnew1")
}
es1x := ldr.AddExtSym("extnew1", 0)
if es1x != 0 {
t.Fatalf("AddExtSym lookup: expected 0 got %d for second lookup", es1x)
}
es2 := ldr.AddExtSym("go.info.type.uint8", 0)
if es2 == 0 {
t.Fatalf("AddExtSym failed for go.info.type.uint8")
}
// Create a nameless symbol
es3 := ldr.CreateExtSym("")
if es3 == 0 {
t.Fatalf("CreateExtSym failed for nameless sym")
}
}