Source file src/cmd/link/internal/ld/typelink.go

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ld
     6  
     7  import (
     8  	"cmd/internal/objabi"
     9  	"cmd/link/internal/loader"
    10  	"cmd/link/internal/sym"
    11  	"sort"
    12  )
    13  
    14  type byTypeStr []typelinkSortKey
    15  
    16  type typelinkSortKey struct {
    17  	TypeStr string
    18  	Type    loader.Sym
    19  }
    20  
    21  func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
    22  func (s byTypeStr) Len() int           { return len(s) }
    23  func (s byTypeStr) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
    24  
    25  // typelink generates the typelink table which is used by reflect.typelinks().
    26  // Types that should be added to the typelinks table are marked with the
    27  // MakeTypelink attribute by the compiler.
    28  func (ctxt *Link) typelink() {
    29  	ldr := ctxt.loader
    30  	typelinks := byTypeStr{}
    31  	var itabs []loader.Sym
    32  	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
    33  		if !ldr.AttrReachable(s) {
    34  			continue
    35  		}
    36  		if ldr.IsTypelink(s) {
    37  			typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ldr, ctxt.Arch, s), s})
    38  		} else if ldr.IsItab(s) {
    39  			itabs = append(itabs, s)
    40  		}
    41  	}
    42  	sort.Sort(typelinks)
    43  
    44  	tl := ldr.CreateSymForUpdate("runtime.typelink", 0)
    45  	tl.SetType(sym.STYPELINK)
    46  	ldr.SetAttrLocal(tl.Sym(), true)
    47  	tl.SetSize(int64(4 * len(typelinks)))
    48  	tl.Grow(tl.Size())
    49  	relocs := tl.AddRelocs(len(typelinks))
    50  	for i, s := range typelinks {
    51  		r := relocs.At(i)
    52  		r.SetSym(s.Type)
    53  		r.SetOff(int32(i * 4))
    54  		r.SetSiz(4)
    55  		r.SetType(objabi.R_ADDROFF)
    56  	}
    57  
    58  	ptrsize := ctxt.Arch.PtrSize
    59  	il := ldr.CreateSymForUpdate("runtime.itablink", 0)
    60  	il.SetType(sym.SITABLINK)
    61  	ldr.SetAttrLocal(il.Sym(), true)
    62  	il.SetSize(int64(ptrsize * len(itabs)))
    63  	il.Grow(il.Size())
    64  	relocs = il.AddRelocs(len(itabs))
    65  	for i, s := range itabs {
    66  		r := relocs.At(i)
    67  		r.SetSym(s)
    68  		r.SetOff(int32(i * ptrsize))
    69  		r.SetSiz(uint8(ptrsize))
    70  		r.SetType(objabi.R_ADDR)
    71  	}
    72  }
    73  

View as plain text