Skip to content
Snippets Groups Projects
loader.go 86.4 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/bio"
	"cmd/internal/goobj2"
	"cmd/internal/obj"
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/sym"
	"os"
	"sort"
	"strconv"
	"strings"
)

var _ = fmt.Print

// 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 int

// 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 []goobj2.Reloc

	li int      // local index of symbol whose relocs we're examining
	r  *oReader // object reader for containing package
	l  *Loader  // loader
}

// Reloc contains the payload for a specific relocation.
// TODO: replace this with sym.Reloc, once we change the
// relocation target from "*sym.Symbol" to "loader.Sym" in sym.Reloc.
type Reloc struct {
	Off  int32            // offset to rewrite
	Size uint8            // number of bytes to rewrite: 0, 1, 2, or 4
	Type objabi.RelocType // the relocation type
	Add  int64            // addend
	Sym  Sym              // global index of symbol the reloc addresses
}

// ExtReloc contains the payload for an external relocation.
type ExtReloc struct {
	Idx  int // index of the original relocation
// Reloc2 holds a "handle" to access a relocation record from an
// object file.
type Reloc2 struct {

	// External reloc types may not fit into a uint8 which the Go object file uses.
	// Store it here, instead of in the byte of goobj2.Reloc2.
	// For Go symbols this will always be zero.
	// goobj2.Reloc2.Type() + typ is always the right type, for both Go and external
	// symbols.
	typ objabi.RelocType
func (rel Reloc2) Type() objabi.RelocType { return objabi.RelocType(rel.Reloc.Type()) + rel.typ }
func (rel Reloc2) Sym() Sym               { return rel.l.resolve(rel.r, rel.Reloc.Sym()) }
func (rel Reloc2) SetSym(s Sym)           { rel.Reloc.SetSym(goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(s)}) }

func (rel Reloc2) SetType(t objabi.RelocType) {
	if t != objabi.RelocType(uint8(t)) {
		panic("SetType: type doesn't fit into Reloc2")
	}
	rel.Reloc.SetType(uint8(t))
	if rel.typ != 0 {
		// should use SymbolBuilder.SetRelocType
		panic("wrong method to set reloc type")
	}
// Aux2 holds a "handle" to access an aux symbol record from an
// object file.
type Aux2 struct {
func (a Aux2) Sym() Sym { return a.l.resolve(a.r, a.Aux.Sym()) }
// oReader is a wrapper type of obj.Reader, along with some
// extra information.
// TODO: rename to objReader once the old one is gone?
type oReader struct {
	*goobj2.Reader
	unit      *sym.CompilationUnit
	version   int    // version of static symbol
	flags     uint32 // read from object file
	syms      []Sym  // Sym's global index, indexed by local index
	ndef      int    // cache goobj2.Reader.NSym()
	objidx    uint32 // index of this reader in the objs slice
// objSym represents a symbol in an object file. It is a tuple of
// the object and the symbol's local index.
// For external symbols, r is l.extReader, s is its index into the
// payload array.
// {nil, 0} represents the nil symbol.
type objSym struct {
	r *oReader
	s int // 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)...)
// A Loader loads new object files and resolves indexed symbol references.
//
// 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.
// - In loader.LoadNonpkgSyms, add non-package defined symbols and
//   references in all object files to the global index space.
//
// - 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.
// - For now, in loader.LoadFull we convert all symbols (Go + external)
//   to sym.Symbols.
//
// - At some point (when the wayfront is pushed through all of the
Loading
Loading full blame...