Newer
Older
// 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
Cherry Zhang
committed
"bytes"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/elf"
"internal/abi"
"os"
"sort"
"strings"
)
var _ = fmt.Print
Than McIntosh
committed
// Sym encapsulates a global symbol index, used to identify a specific
// Go symbol. The 0-valued Sym is corresponds to an invalid symbol.
Than McIntosh
committed
// Relocs encapsulates the set of relocations on a given symbol; an
// instance of this type is returned by the Loader Relocs() method.
type Relocs struct {
Cherry Zhang
committed
li uint32 // local index of symbol whose relocs we're examining
r *oReader // object reader for containing package
l *Loader // loader
}
// ExtReloc contains the payload for an external relocation.
type ExtReloc struct {
Xsym Sym
Xadd int64
Type objabi.RelocType
Size uint8
Cherry Zhang
committed
}
// Reloc holds a "handle" to access a relocation record from an
Cherry Zhang
committed
// object file.
Cherry Zhang
committed
r *oReader
l *Loader
}
func (rel Reloc) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) &^ objabi.R_WEAK }
func (rel Reloc) Weak() bool { return objabi.RelocType(rel.Reloc.Type())&objabi.R_WEAK != 0 }
func (rel Reloc) SetType(t objabi.RelocType) { rel.Reloc.SetType(uint16(t)) }
func (rel Reloc) Sym() Sym { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
func (rel Reloc) SetSym(s Sym) { rel.Reloc.SetSym(goobj.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }
func (rel Reloc) IsMarker() bool { return rel.Siz() == 0 }
Cherry Zhang
committed
// Aux holds a "handle" to access an aux symbol record from an
Cherry Zhang
committed
// object file.
Cherry Zhang
committed
r *oReader
l *Loader
}
func (a Aux) Sym() Sym { return a.l.resolve(a.r, a.Aux.Sym()) }
Cherry Zhang
committed
Cherry Zhang
committed
// oReader is a wrapper type of obj.Reader, along with some
// extra information.
type oReader struct {
Cherry Zhang
committed
unit *sym.CompilationUnit
Cherry Zhang
committed
pkgprefix string
syms []Sym // Sym's global index, indexed by local index
pkg []uint32 // indices of referenced package by PkgIdx (index into loader.objs array)
ndef int // cache goobj.Reader.NSym()
nhashed64def int // cache goobj.Reader.NHashed64Def()
nhasheddef int // cache goobj.Reader.NHashedDef()
objidx uint32 // index of this reader in the objs slice
Cherry Zhang
committed
}
// Total number of defined symbols (package symbols, hashed symbols, and
// non-package symbols).
Cherry Zhang
committed
func (r *oReader) NAlldef() int { return r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef() }
Cherry Zhang
committed
r *oReader
Than McIntosh
committed
i Sym // start index
// objSym represents a symbol in an object file. It is a tuple of
// the object and the symbol's local index.
Cherry Zhang
committed
// For external symbols, objidx is the index of l.extReader (extObj),
// s is its index into the payload array.
// {0, 0} represents the nil symbol.
type objSym struct {
Cherry Zhang
committed
objidx uint32 // index of the object (in l.objs array)
s uint32 // local index
type nameVer struct {
name string
v int
}
func (bm Bitmap) Set(i Sym) {
n, r := uint(i)/32, uint(i)%32
bm[n] |= 1 << r
}
// unset the i-th bit.
func (bm Bitmap) Unset(i Sym) {
n, r := uint(i)/32, uint(i)%32
bm[n] &^= (1 << r)
}
// whether the i-th bit is set.
func (bm Bitmap) Has(i Sym) bool {
n, r := uint(i)/32, uint(i)%32
return bm[n]&(1<<r) != 0
}
Than McIntosh
committed
// return current length of bitmap in bits.
func (bm Bitmap) Len() int {
Than McIntosh
committed
return len(bm) * 32
}
// return the number of bits set.
func (bm Bitmap) Count() int {
s := 0
for _, x := range bm {
s += bits.OnesCount32(x)
}
return s
}
func MakeBitmap(n int) Bitmap {
return make(Bitmap, (n+31)/32)
Than McIntosh
committed
// growBitmap insures that the specified bitmap has enough capacity,
// reallocating (doubling the size) if needed.
func growBitmap(reqLen int, b Bitmap) Bitmap {
curLen := b.Len()
Than McIntosh
committed
if reqLen > curLen {
b = append(b, MakeBitmap(reqLen+1-curLen)...)
Than McIntosh
committed
}
return b
}
type symAndSize struct {
sym Sym
size uint32
Cherry Zhang
committed
}
// A Loader loads new object files and resolves indexed symbol references.
Than McIntosh
committed
//
// Notes on the layout of global symbol index space:
//
// - Go object files are read before host object files; each Go object
// read adds its defined package symbols to the global index space.
// Nonpackage symbols are not yet added.
Than McIntosh
committed
//
// - In loader.LoadNonpkgSyms, add non-package defined symbols and
// references in all object files to the global index space.
Than McIntosh
committed
//
// - Host object file loading happens; the host object loader does a
// name/version lookup for each symbol it finds; this can wind up
// extending the external symbol index space range. The host object
// loader stores symbol payloads in loader.payloads using SymbolBuilder.
Than McIntosh
committed
//
// - Each symbol gets a unique global index. For duplicated and
// overwriting/overwritten symbols, the second (or later) appearance
// of the symbol gets the same global index as the first appearance.
start map[*oReader]Sym // map from object file to its start index
objs []objIdx // sorted by start index (i.e. objIdx.i)
extStart Sym // from this index on, the symbols are externally defined
builtinSyms []Sym // global index of builtin symbols
objSyms []objSym // global index mapping to local index
symsByName [2]map[string]Sym // map symbol name to index, two maps are for ABI0 and ABIInternal
extStaticSyms map[nameVer]Sym // externally defined static symbols, keyed by name
extReader *oReader // a dummy oReader, for external symbols
payloadBatch []extSymPayload
payloads []*extSymPayload // contents of linker-materialized external syms
values []int64 // symbol values, indexed by global sym index
Loading
Loading full blame...