Skip to content
Snippets Groups Projects
loader.go 79.3 KiB
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.

	"cmd/internal/goobj"
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/sym"
// Sym encapsulates a global symbol index, used to identify a specific
// Go symbol. The 0-valued Sym is corresponds to an invalid symbol.
type Sym uint32
// 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 {
	rs []goobj.Reloc
	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
// Reloc holds a "handle" to access a relocation record from an
type Reloc struct {
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 }
// Aux holds a "handle" to access an aux symbol record from an
type Aux struct {
func (a Aux) Sym() Sym { return a.l.resolve(a.r, a.Aux.Sym()) }
// oReader is a wrapper type of obj.Reader, along with some
// extra information.
type oReader struct {
	version      int // version of static symbol
	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
// Total number of defined symbols (package symbols, hashed symbols, and
// non-package symbols).
func (r *oReader) NAlldef() int { return r.ndef + r.nhashed64def + r.nhasheddef + r.NNonpkgdef() }
type objIdx struct {
// objSym represents a symbol in an object file. It is a tuple of
// the object and the symbol's local index.
// 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.
	objidx uint32 // index of the object (in l.objs array)
	s      uint32 // local index
type nameVer struct {
	name string
	v    int
}

type Bitmap []uint32

// set the i-th bit.
func (bm Bitmap) Set(i Sym) {
	n, r := uint(i)/32, uint(i)%32
	bm[n] |= 1 << r
}

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
}

// return current length of bitmap in bits.
func (bm Bitmap) Len() int {

// 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)
// 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()
		b = append(b, MakeBitmap(reqLen+1-curLen)...)
type symAndSize struct {
	sym  Sym
	size uint32
// A Loader loads new object files and resolves indexed symbol references.
//
// Notes on the layout of global symbol index space:
//
Russ Cox's avatar
Russ Cox committed
//   - 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.
Russ Cox's avatar
Russ Cox committed
//   - In loader.LoadNonpkgSyms, add non-package defined symbols and
//     references in all object files to the global index space.
Russ Cox's avatar
Russ Cox 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.
Russ Cox's avatar
Russ Cox 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...