Commit c9470b04 authored by Than McIntosh's avatar Than McIntosh

[dev.link] cmd/link/internal/objfile: relocate loader to new package

Third change of several to update the loader API to reflect the final
consensus version of the loader API as described in Cherry's doc.
This piece:

   - move objfile.Loader into its own separate package, and update
     clients accordingly.

This includes a few minor cleanups, including converting a couple
of loader-related functions to methods, and privatizing some of the
loader methods such as ToGlobal/ToLocal.

Change-Id: Iae20585751a45491d8b19dcffc096aadae6bbfc6
Reviewed-on: https://go-review.googlesource.com/c/go/+/200998
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: default avatarJeremy Faller <jeremy@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 4a9b30cf
...@@ -73,6 +73,7 @@ var bootstrapDirs = []string{ ...@@ -73,6 +73,7 @@ var bootstrapDirs = []string{
"cmd/link/internal/arm64", "cmd/link/internal/arm64",
"cmd/link/internal/ld", "cmd/link/internal/ld",
"cmd/link/internal/loadelf", "cmd/link/internal/loadelf",
"cmd/link/internal/loader",
"cmd/link/internal/loadmacho", "cmd/link/internal/loadmacho",
"cmd/link/internal/loadpe", "cmd/link/internal/loadpe",
"cmd/link/internal/loadxcoff", "cmd/link/internal/loadxcoff",
......
This diff is collapsed.
...@@ -38,6 +38,7 @@ import ( ...@@ -38,6 +38,7 @@ import (
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/loadelf" "cmd/link/internal/loadelf"
"cmd/link/internal/loader"
"cmd/link/internal/loadmacho" "cmd/link/internal/loadmacho"
"cmd/link/internal/loadpe" "cmd/link/internal/loadpe"
"cmd/link/internal/loadxcoff" "cmd/link/internal/loadxcoff"
...@@ -376,7 +377,7 @@ func (ctxt *Link) findLibPath(libname string) string { ...@@ -376,7 +377,7 @@ func (ctxt *Link) findLibPath(libname string) string {
func (ctxt *Link) loadlib() { func (ctxt *Link) loadlib() {
if *flagNewobj { if *flagNewobj {
ctxt.loader = objfile.NewLoader() ctxt.loader = loader.NewLoader()
} }
ctxt.cgo_export_static = make(map[string]bool) ctxt.cgo_export_static = make(map[string]bool)
...@@ -434,7 +435,7 @@ func (ctxt *Link) loadlib() { ...@@ -434,7 +435,7 @@ func (ctxt *Link) loadlib() {
if *flagNewobj { if *flagNewobj {
// Add references of externally defined symbols. // Add references of externally defined symbols.
objfile.LoadRefs(ctxt.loader, ctxt.Arch, ctxt.Syms) ctxt.loader.LoadRefs(ctxt.Arch, ctxt.Syms)
} }
// Now that we know the link mode, set the dynexp list. // Now that we know the link mode, set the dynexp list.
...@@ -1772,7 +1773,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, ...@@ -1772,7 +1773,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
} }
var c int var c int
if *flagNewobj { if *flagNewobj {
objfile.LoadNew(ctxt.loader, ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags) ctxt.loader.Preload(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
} else { } else {
c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags) c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
} }
...@@ -2550,7 +2551,7 @@ func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library ...@@ -2550,7 +2551,7 @@ func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library
func (ctxt *Link) loadlibfull() { func (ctxt *Link) loadlibfull() {
// Load full symbol contents, resolve indexed references. // Load full symbol contents, resolve indexed references.
objfile.LoadFull(ctxt.loader, ctxt.Arch, ctxt.Syms) ctxt.loader.LoadFull(ctxt.Arch, ctxt.Syms)
// For now, add all symbols to ctxt.Syms. // For now, add all symbols to ctxt.Syms.
for _, s := range ctxt.loader.Syms { for _, s := range ctxt.loader.Syms {
......
...@@ -35,7 +35,7 @@ import ( ...@@ -35,7 +35,7 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/objfile" "cmd/link/internal/loader"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"debug/elf" "debug/elf"
"fmt" "fmt"
...@@ -98,7 +98,7 @@ type Link struct { ...@@ -98,7 +98,7 @@ type Link struct {
relocbuf []byte // temporary buffer for applying relocations relocbuf []byte // temporary buffer for applying relocations
loader *objfile.Loader loader *loader.Loader
cgodata []cgodata // cgo directives to load, three strings are args for loadcgo cgodata []cgodata // cgo directives to load, three strings are args for loadcgo
cgo_export_static map[string]bool cgo_export_static map[string]bool
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package objfile package loader
import ( import (
"bytes" "bytes"
...@@ -87,8 +87,6 @@ func makeBitmap(n int) bitmap { ...@@ -87,8 +87,6 @@ func makeBitmap(n int) bitmap {
} }
// A Loader loads new object files and resolves indexed symbol references. // A Loader loads new object files and resolves indexed symbol references.
//
// TODO: describe local-global index mapping.
type Loader struct { type Loader struct {
start map[*oReader]Sym // map from object file to its start index start map[*oReader]Sym // map from object file to its start index
objs []objIdx // sorted by start index (i.e. objIdx.i) objs []objIdx // sorted by start index (i.e. objIdx.i)
...@@ -117,12 +115,12 @@ func NewLoader() *Loader { ...@@ -117,12 +115,12 @@ func NewLoader() *Loader {
} }
// Return the start index in the global index space for a given object file. // Return the start index in the global index space for a given object file.
func (l *Loader) StartIndex(r *oReader) Sym { func (l *Loader) startIndex(r *oReader) Sym {
return l.start[r] return l.start[r]
} }
// Add object file r, return the start index. // Add object file r, return the start index.
func (l *Loader) AddObj(pkg string, r *oReader) Sym { func (l *Loader) addObj(pkg string, r *oReader) Sym {
if _, ok := l.start[r]; ok { if _, ok := l.start[r]; ok {
panic("already added") panic("already added")
} }
...@@ -148,10 +146,10 @@ func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ ...@@ -148,10 +146,10 @@ func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ
if dupok { if dupok {
return false return false
} }
overwrite := r.DataSize(int(i-l.StartIndex(r))) != 0 overwrite := r.DataSize(int(i-l.startIndex(r))) != 0
if overwrite { if overwrite {
// new symbol overwrites old symbol. // new symbol overwrites old symbol.
oldr, li := l.ToLocal(oldi) oldr, li := l.toLocal(oldi)
oldsym := goobj2.Sym{} oldsym := goobj2.Sym{}
oldsym.Read(oldr.Reader, oldr.SymOff(li)) oldsym.Read(oldr.Reader, oldr.SymOff(li))
oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type)] oldtyp := sym.AbiSymKindToSymKind[objabi.SymKind(oldsym.Type)]
...@@ -190,8 +188,8 @@ func (l *Loader) AddExtSym(name string, ver int) Sym { ...@@ -190,8 +188,8 @@ func (l *Loader) AddExtSym(name string, ver int) Sym {
} }
// Convert a local index to a global index. // Convert a local index to a global index.
func (l *Loader) ToGlobal(r *oReader, i int) Sym { func (l *Loader) toGlobal(r *oReader, i int) Sym {
g := l.StartIndex(r) + Sym(i) g := l.startIndex(r) + Sym(i)
if ov, ok := l.overwrite[g]; ok { if ov, ok := l.overwrite[g]; ok {
return ov return ov
} }
...@@ -199,7 +197,7 @@ func (l *Loader) ToGlobal(r *oReader, i int) Sym { ...@@ -199,7 +197,7 @@ func (l *Loader) ToGlobal(r *oReader, i int) Sym {
} }
// Convert a global index to a local index. // Convert a global index to a local index.
func (l *Loader) ToLocal(i Sym) (*oReader, int) { func (l *Loader) toLocal(i Sym) (*oReader, int) {
if ov, ok := l.overwrite[i]; ok { if ov, ok := l.overwrite[i]; ok {
i = ov i = ov
} }
...@@ -216,7 +214,7 @@ func (l *Loader) ToLocal(i Sym) (*oReader, int) { ...@@ -216,7 +214,7 @@ func (l *Loader) ToLocal(i Sym) (*oReader, int) {
} }
// Resolve a local symbol reference. Return global index. // Resolve a local symbol reference. Return global index.
func (l *Loader) Resolve(r *oReader, s goobj2.SymRef) Sym { func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
var rr *oReader var rr *oReader
switch p := s.PkgIdx; p { switch p := s.PkgIdx; p {
case goobj2.PkgIdxInvalid: case goobj2.PkgIdxInvalid:
...@@ -245,7 +243,7 @@ func (l *Loader) Resolve(r *oReader, s goobj2.SymRef) Sym { ...@@ -245,7 +243,7 @@ func (l *Loader) Resolve(r *oReader, s goobj2.SymRef) Sym {
log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib) log.Fatalf("reference of nonexisted package %s, from %v", pkg, r.unit.Lib)
} }
} }
return l.ToGlobal(rr, int(s.SymIdx)) return l.toGlobal(rr, int(s.SymIdx))
} }
// Look up a symbol by name, return global index, or 0 if not found. // Look up a symbol by name, return global index, or 0 if not found.
...@@ -266,7 +264,7 @@ func (l *Loader) RawSymName(i Sym) string { ...@@ -266,7 +264,7 @@ func (l *Loader) RawSymName(i Sym) string {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return "" return ""
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.Read(r.Reader, r.SymOff(li))
return osym.Name return osym.Name
...@@ -277,7 +275,7 @@ func (l *Loader) SymName(i Sym) string { ...@@ -277,7 +275,7 @@ func (l *Loader) SymName(i Sym) string {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return "" return ""
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.Read(r.Reader, r.SymOff(li))
return strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1) return strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1)
...@@ -288,7 +286,7 @@ func (l *Loader) SymType(i Sym) sym.SymKind { ...@@ -288,7 +286,7 @@ func (l *Loader) SymType(i Sym) sym.SymKind {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return 0 return 0
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.Read(r.Reader, r.SymOff(li))
return sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)] return sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]
...@@ -299,7 +297,7 @@ func (l *Loader) SymAttr(i Sym) uint8 { ...@@ -299,7 +297,7 @@ func (l *Loader) SymAttr(i Sym) uint8 {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return 0 return 0
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.Read(r.Reader, r.SymOff(li))
return osym.Flag return osym.Flag
...@@ -315,7 +313,7 @@ func (l *Loader) Data(i Sym) []byte { ...@@ -315,7 +313,7 @@ func (l *Loader) Data(i Sym) []byte {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return nil return nil
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
return r.Data(li) return r.Data(li)
} }
...@@ -324,7 +322,7 @@ func (l *Loader) NAux(i Sym) int { ...@@ -324,7 +322,7 @@ func (l *Loader) NAux(i Sym) int {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return 0 return 0
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
return r.NAux(li) return r.NAux(li)
} }
...@@ -334,10 +332,10 @@ func (l *Loader) AuxSym(i Sym, j int) Sym { ...@@ -334,10 +332,10 @@ func (l *Loader) AuxSym(i Sym, j int) Sym {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return 0 return 0
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
a := goobj2.Aux{} a := goobj2.Aux{}
a.Read(r.Reader, r.AuxOff(li, j)) a.Read(r.Reader, r.AuxOff(li, j))
return l.Resolve(r, a.Sym) return l.resolve(r, a.Sym)
} }
// Initialize Reachable bitmap for running deadcode pass. // Initialize Reachable bitmap for running deadcode pass.
...@@ -349,7 +347,7 @@ func (l *Loader) InitReachable() { ...@@ -349,7 +347,7 @@ func (l *Loader) InitReachable() {
func (relocs *Relocs) At(j int) Reloc { func (relocs *Relocs) At(j int) Reloc {
rel := goobj2.Reloc{} rel := goobj2.Reloc{}
rel.Read(relocs.r.Reader, relocs.r.RelocOff(relocs.li, j)) rel.Read(relocs.r.Reader, relocs.r.RelocOff(relocs.li, j))
target := relocs.l.Resolve(relocs.r, rel.Sym) target := relocs.l.resolve(relocs.r, rel.Sym)
return Reloc{ return Reloc{
Off: rel.Off, Off: rel.Off,
Size: rel.Siz, Size: rel.Siz,
...@@ -364,7 +362,7 @@ func (l *Loader) Relocs(i Sym) Relocs { ...@@ -364,7 +362,7 @@ func (l *Loader) Relocs(i Sym) Relocs {
if l.extStart != 0 && i >= l.extStart { if l.extStart != 0 && i >= l.extStart {
return Relocs{} return Relocs{}
} }
r, li := l.ToLocal(i) r, li := l.toLocal(i)
return l.relocs(r, li) return l.relocs(r, li)
} }
...@@ -380,7 +378,7 @@ func (l *Loader) relocs(r *oReader, li int) Relocs { ...@@ -380,7 +378,7 @@ func (l *Loader) relocs(r *oReader, li int) Relocs {
// Preload a package: add autolibs, add symbols to the symbol table. // Preload a package: add autolibs, add symbols to the symbol table.
// Does not read symbol data yet. // Does not read symbol data yet.
func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64, pn string, flags int) { func (l *Loader) Preload(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *sym.Library, unit *sym.CompilationUnit, length int64, pn string, flags int) {
roObject, readonly, err := f.Slice(uint64(length)) roObject, readonly, err := f.Slice(uint64(length))
if err != nil { if err != nil {
log.Fatal("cannot read object file:", err) log.Fatal("cannot read object file:", err)
...@@ -403,7 +401,7 @@ func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *s ...@@ -403,7 +401,7 @@ func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *s
unit.DWARFFileTable[i] = r.DwarfFile(i) unit.DWARFFileTable[i] = r.DwarfFile(i)
} }
istart := l.AddObj(lib.Pkg, or) istart := l.addObj(lib.Pkg, or)
ndef := r.NSym() ndef := r.NSym()
nnonpkgdef := r.NNonpkgdef() nnonpkgdef := r.NNonpkgdef()
...@@ -425,7 +423,7 @@ func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *s ...@@ -425,7 +423,7 @@ func LoadNew(l *Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *s
// Make sure referenced symbols are added. Most of them should already be added. // Make sure referenced symbols are added. Most of them should already be added.
// This should only be needed for referenced external symbols. // This should only be needed for referenced external symbols.
func LoadRefs(l *Loader, arch *sys.Arch, syms *sym.Symbols) { func (l *Loader) LoadRefs(arch *sys.Arch, syms *sym.Symbols) {
for _, o := range l.objs[1:] { for _, o := range l.objs[1:] {
loadObjRefs(l, o.r, arch, syms) loadObjRefs(l, o.r, arch, syms)
} }
...@@ -479,7 +477,7 @@ func preprocess(arch *sys.Arch, s *sym.Symbol) { ...@@ -479,7 +477,7 @@ func preprocess(arch *sys.Arch, s *sym.Symbol) {
} }
// Load full contents. // Load full contents.
func LoadFull(l *Loader, arch *sys.Arch, syms *sym.Symbols) { func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) {
// create all Symbols first. // create all Symbols first.
l.Syms = make([]*sym.Symbol, l.NSym()) l.Syms = make([]*sym.Symbol, l.NSym())
for _, o := range l.objs[1:] { for _, o := range l.objs[1:] {
...@@ -505,7 +503,7 @@ func LoadFull(l *Loader, arch *sys.Arch, syms *sym.Symbols) { ...@@ -505,7 +503,7 @@ func LoadFull(l *Loader, arch *sys.Arch, syms *sym.Symbols) {
func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) { func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) {
lib := r.unit.Lib lib := r.unit.Lib
istart := l.StartIndex(r) istart := l.startIndex(r)
for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ { for i, n := 0, r.NSym()+r.NNonpkgdef(); i < n; i++ {
osym := goobj2.Sym{} osym := goobj2.Sym{}
...@@ -550,10 +548,10 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) { ...@@ -550,10 +548,10 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) {
func loadObjFull(l *Loader, r *oReader) { func loadObjFull(l *Loader, r *oReader) {
lib := r.unit.Lib lib := r.unit.Lib
istart := l.StartIndex(r) istart := l.startIndex(r)
resolveSymRef := func(s goobj2.SymRef) *sym.Symbol { resolveSymRef := func(s goobj2.SymRef) *sym.Symbol {
i := l.Resolve(r, s) i := l.resolve(r, s)
return l.Syms[i] return l.Syms[i]
} }
...@@ -735,7 +733,7 @@ func loadObjFull(l *Loader, r *oReader) { ...@@ -735,7 +733,7 @@ func loadObjFull(l *Loader, r *oReader) {
Parent: inl.Parent, Parent: inl.Parent,
File: resolveSymRef(inl.File), File: resolveSymRef(inl.File),
Line: inl.Line, Line: inl.Line,
Func: l.SymName(l.Resolve(r, inl.Func)), Func: l.SymName(l.resolve(r, inl.Func)),
ParentPC: inl.ParentPC, ParentPC: inl.ParentPC,
} }
} }
...@@ -754,6 +752,8 @@ func loadObjFull(l *Loader, r *oReader) { ...@@ -754,6 +752,8 @@ func loadObjFull(l *Loader, r *oReader) {
} }
} }
var emptyPkg = []byte(`"".`)
func patchDWARFName(s *sym.Symbol, r *oReader) { func patchDWARFName(s *sym.Symbol, r *oReader) {
// This is kind of ugly. Really the package name should not // This is kind of ugly. Really the package name should not
// even be included here. // even be included here.
......
...@@ -10,7 +10,7 @@ import ( ...@@ -10,7 +10,7 @@ import (
"cmd/internal/bio" "cmd/internal/bio"
"cmd/internal/objabi" "cmd/internal/objabi"
"cmd/internal/sys" "cmd/internal/sys"
"cmd/link/internal/objfile" "cmd/link/internal/loader"
"cmd/link/internal/sym" "cmd/link/internal/sym"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
...@@ -424,7 +424,7 @@ func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int { ...@@ -424,7 +424,7 @@ func macholoadsym(m *ldMachoObj, symtab *ldMachoSymtab) int {
return 0 return 0
} }
func Load(l *objfile.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string) error { func Load(l *loader.Loader, arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, pkg string, length int64, pn string) error {
lookup := func(name string, version int) *sym.Symbol { lookup := func(name string, version int) *sym.Symbol {
// Check to see if we've already defined the symbol. // Check to see if we've already defined the symbol.
if i := l.Lookup(name, version); i != 0 { if i := l.Lookup(name, version); i != 0 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment