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