• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5package ld
6
7import (
8	"cmd/internal/objabi"
9	"cmd/link/internal/loader"
10	"cmd/link/internal/sym"
11	"sort"
12)
13
14type byTypeStr []typelinkSortKey
15
16type typelinkSortKey struct {
17	TypeStr string
18	Type    loader.Sym
19}
20
21func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
22func (s byTypeStr) Len() int           { return len(s) }
23func (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.
28func (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