mirror of
https://github.com/golang/go
synced 2024-11-05 18:56:10 -07:00
cmd/link: split "bag of Symbols" functionality out of Link
Mechanical refactorings to follow. Change-Id: I9b98e69a58c3cba7c7d1d3e3f600d4ed99d4fce2 Reviewed-on: https://go-review.googlesource.com/29342 Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
e9fddf8f86
commit
d284d4ff92
@ -173,27 +173,22 @@ type Shlib struct {
|
|||||||
// Link holds the context for writing object code from a compiler
|
// Link holds the context for writing object code from a compiler
|
||||||
// or for reading that input into the linker.
|
// or for reading that input into the linker.
|
||||||
type Link struct {
|
type Link struct {
|
||||||
|
Symbols
|
||||||
|
|
||||||
Arch *sys.Arch
|
Arch *sys.Arch
|
||||||
Debugvlog int
|
Debugvlog int
|
||||||
Bso *bufio.Writer
|
Bso *bufio.Writer
|
||||||
|
|
||||||
Loaded bool // set after all inputs have been loaded as symbols
|
Loaded bool // set after all inputs have been loaded as symbols
|
||||||
|
|
||||||
// Symbol lookup based on name and indexed by version.
|
|
||||||
Hash []map[string]*Symbol
|
|
||||||
|
|
||||||
Allsym []*Symbol
|
|
||||||
Tlsg *Symbol
|
Tlsg *Symbol
|
||||||
Libdir []string
|
Libdir []string
|
||||||
Library []*Library
|
Library []*Library
|
||||||
Shlibs []Shlib
|
Shlibs []Shlib
|
||||||
Tlsoffset int
|
Tlsoffset int
|
||||||
|
|
||||||
Version int
|
|
||||||
Textp []*Symbol
|
Textp []*Symbol
|
||||||
Filesyms []*Symbol
|
Filesyms []*Symbol
|
||||||
Moduledata *Symbol
|
Moduledata *Symbol
|
||||||
SymbolBatch []Symbol
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The smallest possible offset from the hardware stack pointer to a local
|
// The smallest possible offset from the hardware stack pointer to a local
|
||||||
@ -213,11 +208,6 @@ func (ctxt *Link) FixedFrameSize() int64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *Link) IncVersion() {
|
|
||||||
l.Version++
|
|
||||||
l.Hash = append(l.Hash, make(map[string]*Symbol))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l *Link) Logf(format string, args ...interface{}) {
|
func (l *Link) Logf(format string, args ...interface{}) {
|
||||||
fmt.Fprintf(l.Bso, format, args...)
|
fmt.Fprintf(l.Bso, format, args...)
|
||||||
l.Bso.Flush()
|
l.Bso.Flush()
|
||||||
|
@ -39,12 +39,14 @@ import (
|
|||||||
|
|
||||||
func linknew(arch *sys.Arch) *Link {
|
func linknew(arch *sys.Arch) *Link {
|
||||||
ctxt := &Link{
|
ctxt := &Link{
|
||||||
Hash: []map[string]*Symbol{
|
Symbols: Symbols{
|
||||||
|
hash: []map[string]*Symbol{
|
||||||
// preallocate about 2mb for hash of
|
// preallocate about 2mb for hash of
|
||||||
// non static symbols
|
// non static symbols
|
||||||
make(map[string]*Symbol, 100000),
|
make(map[string]*Symbol, 100000),
|
||||||
},
|
},
|
||||||
Allsym: make([]*Symbol, 0, 100000),
|
Allsym: make([]*Symbol, 0, 100000),
|
||||||
|
},
|
||||||
Arch: arch,
|
Arch: arch,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,36 +134,14 @@ func (ctxt *Link) computeTLSOffset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func linknewsym(ctxt *Link, name string, v int) *Symbol {
|
func linknewsym(ctxt *Link, name string, v int) *Symbol {
|
||||||
batch := ctxt.SymbolBatch
|
return ctxt.newsym(name, v)
|
||||||
if len(batch) == 0 {
|
|
||||||
batch = make([]Symbol, 1000)
|
|
||||||
}
|
|
||||||
s := &batch[0]
|
|
||||||
ctxt.SymbolBatch = batch[1:]
|
|
||||||
|
|
||||||
s.Dynid = -1
|
|
||||||
s.Plt = -1
|
|
||||||
s.Got = -1
|
|
||||||
s.Name = name
|
|
||||||
s.Version = int16(v)
|
|
||||||
ctxt.Allsym = append(ctxt.Allsym, s)
|
|
||||||
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Linklookup(ctxt *Link, name string, v int) *Symbol {
|
func Linklookup(ctxt *Link, name string, v int) *Symbol {
|
||||||
m := ctxt.Hash[v]
|
return ctxt.Lookup(name, v)
|
||||||
s := m[name]
|
|
||||||
if s != nil {
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
s = linknewsym(ctxt, name, v)
|
|
||||||
s.Extname = s.Name
|
|
||||||
m[name] = s
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read-only lookup
|
// read-only lookup
|
||||||
func Linkrlookup(ctxt *Link, name string, v int) *Symbol {
|
func Linkrlookup(ctxt *Link, name string, v int) *Symbol {
|
||||||
return ctxt.Hash[v][name]
|
return ctxt.ROLookup(name, v)
|
||||||
}
|
}
|
||||||
|
90
src/cmd/link/internal/ld/symbols.go
Normal file
90
src/cmd/link/internal/ld/symbols.go
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
// Derived from Inferno utils/6l/l.h and related files.
|
||||||
|
// https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
|
||||||
|
//
|
||||||
|
// Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved.
|
||||||
|
// Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Portions Copyright © 1997-1999 Vita Nuova Limited
|
||||||
|
// Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
|
||||||
|
// Portions Copyright © 2004,2006 Bruce Ellis
|
||||||
|
// Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
|
||||||
|
// Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
|
||||||
|
// Portions Copyright © 2009 The Go Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
|
||||||
|
package ld
|
||||||
|
|
||||||
|
type Symbols struct {
|
||||||
|
symbolBatch []Symbol
|
||||||
|
|
||||||
|
// Symbol lookup based on name and indexed by version.
|
||||||
|
hash []map[string]*Symbol
|
||||||
|
|
||||||
|
Allsym []*Symbol
|
||||||
|
|
||||||
|
Version int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (syms *Symbols) newsym(name string, v int) *Symbol {
|
||||||
|
batch := syms.symbolBatch
|
||||||
|
if len(batch) == 0 {
|
||||||
|
batch = make([]Symbol, 1000)
|
||||||
|
}
|
||||||
|
s := &batch[0]
|
||||||
|
syms.symbolBatch = batch[1:]
|
||||||
|
|
||||||
|
s.Dynid = -1
|
||||||
|
s.Plt = -1
|
||||||
|
s.Got = -1
|
||||||
|
s.Name = name
|
||||||
|
s.Version = int16(v)
|
||||||
|
syms.Allsym = append(syms.Allsym, s)
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up the symbol with the given name and version, creating the
|
||||||
|
// symbol if it is not found.
|
||||||
|
func (syms *Symbols) Lookup(name string, v int) *Symbol {
|
||||||
|
m := syms.hash[v]
|
||||||
|
s := m[name]
|
||||||
|
if s != nil {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
s = syms.newsym(name, v)
|
||||||
|
s.Extname = s.Name
|
||||||
|
m[name] = s
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up the symbol with the given name and version, returning nil
|
||||||
|
// if it is not found.
|
||||||
|
func (syms *Symbols) ROLookup(name string, v int) *Symbol {
|
||||||
|
return syms.hash[v][name]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate a new version (i.e. symbol namespace).
|
||||||
|
//
|
||||||
|
// TODO(mwhudson): This would feel more natural if it returned the new
|
||||||
|
// version (or if we dropped Symbols.Version entirely and just
|
||||||
|
// returned len(syms.hash))
|
||||||
|
func (syms *Symbols) IncVersion() {
|
||||||
|
syms.Version++
|
||||||
|
syms.hash = append(syms.hash, make(map[string]*Symbol))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user