diff options
Diffstat (limited to 'src/cmd/oldlink/internal/ld/typelink.go')
-rw-r--r-- | src/cmd/oldlink/internal/ld/typelink.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/cmd/oldlink/internal/ld/typelink.go b/src/cmd/oldlink/internal/ld/typelink.go new file mode 100644 index 0000000000..07d04bb13d --- /dev/null +++ b/src/cmd/oldlink/internal/ld/typelink.go @@ -0,0 +1,49 @@ +// Copyright 2016 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. + +package ld + +import ( + "cmd/internal/objabi" + "cmd/oldlink/internal/sym" + "sort" +) + +type byTypeStr []typelinkSortKey + +type typelinkSortKey struct { + TypeStr string + Type *sym.Symbol +} + +func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr } +func (s byTypeStr) Len() int { return len(s) } +func (s byTypeStr) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// typelink generates the typelink table which is used by reflect.typelinks(). +// Types that should be added to the typelinks table are marked with the +// MakeTypelink attribute by the compiler. +func (ctxt *Link) typelink() { + typelinks := byTypeStr{} + for _, s := range ctxt.Syms.Allsym { + if s.Attr.Reachable() && s.Attr.MakeTypelink() { + typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ctxt.Arch, s), s}) + } + } + sort.Sort(typelinks) + + tl := ctxt.Syms.Lookup("runtime.typelink", 0) + tl.Type = sym.STYPELINK + tl.Attr |= sym.AttrReachable | sym.AttrLocal + tl.Size = int64(4 * len(typelinks)) + tl.P = make([]byte, tl.Size) + tl.R = make([]sym.Reloc, len(typelinks)) + for i, s := range typelinks { + r := &tl.R[i] + r.Sym = s.Type + r.Off = int32(i * 4) + r.Siz = 4 + r.Type = objabi.R_ADDROFF + } +} |