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  	"slices"
    12  	"strings"
    13  )
    14  
    15  type typelinkSortKey struct {
    16  	TypeStr string
    17  	Type    loader.Sym
    18  }
    19  
    20  // typelink generates the typelink table which is used by reflect.typelinks().
    21  // Types that should be added to the typelinks table are marked with the
    22  // MakeTypelink attribute by the compiler.
    23  func (ctxt *Link) typelink() {
    24  	ldr := ctxt.loader
    25  	var typelinks []typelinkSortKey
    26  	var itabs []loader.Sym
    27  	for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
    28  		if !ldr.AttrReachable(s) {
    29  			continue
    30  		}
    31  		if ldr.IsTypelink(s) {
    32  			typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ldr, ctxt.Arch, s), s})
    33  		} else if ldr.IsItab(s) {
    34  			itabs = append(itabs, s)
    35  		}
    36  	}
    37  	slices.SortFunc(typelinks, func(a, b typelinkSortKey) int {
    38  		return strings.Compare(a.TypeStr, b.TypeStr)
    39  	})
    40  
    41  	tl := ldr.CreateSymForUpdate("runtime.typelink", 0)
    42  	tl.SetType(sym.STYPELINK)
    43  	ldr.SetAttrLocal(tl.Sym(), true)
    44  	tl.SetSize(int64(4 * len(typelinks)))
    45  	tl.Grow(tl.Size())
    46  	relocs := tl.AddRelocs(len(typelinks))
    47  	for i, s := range typelinks {
    48  		r := relocs.At(i)
    49  		r.SetSym(s.Type)
    50  		r.SetOff(int32(i * 4))
    51  		r.SetSiz(4)
    52  		r.SetType(objabi.R_ADDROFF)
    53  	}
    54  
    55  	ptrsize := ctxt.Arch.PtrSize
    56  	il := ldr.CreateSymForUpdate("runtime.itablink", 0)
    57  	il.SetType(sym.SITABLINK)
    58  	ldr.SetAttrLocal(il.Sym(), true)
    59  	il.SetSize(int64(ptrsize * len(itabs)))
    60  	il.Grow(il.Size())
    61  	relocs = il.AddRelocs(len(itabs))
    62  	for i, s := range itabs {
    63  		r := relocs.At(i)
    64  		r.SetSym(s)
    65  		r.SetOff(int32(i * ptrsize))
    66  		r.SetSiz(uint8(ptrsize))
    67  		r.SetType(objabi.R_ADDR)
    68  	}
    69  }
    70  

View as plain text