Commit 475d92ba authored by David Crawshaw's avatar David Crawshaw

cmd/link: put symbol data types in new package

For #22095

Change-Id: I07c288208d94dabae164c2ca0a067402a8e5c2e6
Reviewed-on: https://go-review.googlesource.com/68331
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarIan Lance Taylor <iant@golang.org>
parent 24e4a128
......@@ -70,6 +70,7 @@ var bootstrapDirs = []string{
"cmd/link/internal/mips64",
"cmd/link/internal/ppc64",
"cmd/link/internal/s390x",
"cmd/link/internal/sym",
"cmd/link/internal/x86",
"debug/pe",
"math/big",
......
This diff is collapsed.
This diff is collapsed.
......@@ -34,6 +34,7 @@ import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/ld"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"log"
......@@ -44,16 +45,16 @@ func gentext(ctxt *ld.Link) {
return
}
addmoduledata := ctxt.Syms.Lookup("runtime.addmoduledata", 0)
if addmoduledata.Type == ld.STEXT {
if addmoduledata.Type == sym.STEXT {
// we're linking a module containing the runtime -> no need for
// an init function
return
}
addmoduledata.Attr |= ld.AttrReachable
addmoduledata.Attr |= sym.AttrReachable
initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
initfunc.Type = ld.STEXT
initfunc.Attr |= ld.AttrLocal
initfunc.Attr |= ld.AttrReachable
initfunc.Type = sym.STEXT
initfunc.Attr |= sym.AttrLocal
initfunc.Attr |= sym.AttrReachable
o := func(op uint32) {
initfunc.AddUint32(ctxt.Arch, op)
}
......@@ -81,18 +82,18 @@ func gentext(ctxt *ld.Link) {
ctxt.Textp = append(ctxt.Textp, initfunc)
initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
initarray_entry.Attr |= ld.AttrReachable
initarray_entry.Attr |= ld.AttrLocal
initarray_entry.Type = ld.SINITARR
initarray_entry.Attr |= sym.AttrReachable
initarray_entry.Attr |= sym.AttrLocal
initarray_entry.Type = sym.SINITARR
initarray_entry.AddAddr(ctxt.Arch, initfunc)
}
func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
func adddynrel(ctxt *ld.Link, s *sym.Symbol, r *sym.Reloc) bool {
log.Fatalf("adddynrel not implemented")
return false
}
func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) bool {
func elfreloc1(ctxt *ld.Link, r *sym.Reloc, sectoff int64) bool {
ctxt.Out.Write64(uint64(sectoff))
elfsym := r.Xsym.ElfsymForReloc()
......@@ -143,7 +144,7 @@ func elfsetupplt(ctxt *ld.Link) {
return
}
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sectoff int64) bool {
func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *sym.Symbol, r *sym.Reloc, sectoff int64) bool {
var v uint32
rs := r.Xsym
......@@ -151,9 +152,9 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
// ld64 has a bug handling MACHO_ARM64_RELOC_UNSIGNED with !extern relocation.
// see cmd/internal/ld/data.go for details. The workaround is that don't use !extern
// UNSIGNED relocation at all.
if rs.Type == ld.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
if rs.Type == sym.SHOSTOBJ || r.Type == objabi.R_CALLARM64 || r.Type == objabi.R_ADDRARM64 || r.Type == objabi.R_ADDR {
if rs.Dynid < 0 {
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to non-macho symbol %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Type, rs.Type)
return false
}
......@@ -162,7 +163,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
} else {
v = uint32(rs.Sect.Extnum)
if v == 0 {
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, ld.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
ld.Errorf(s, "reloc %d (%s) to symbol %s in non-macho section %s type=%d (%s)", r.Type, sym.RelocName(arch, r.Type), rs.Name, rs.Sect.Name, rs.Type, rs.Type)
return false
}
}
......@@ -215,7 +216,7 @@ func machoreloc1(arch *sys.Arch, out *ld.OutBuf, s *ld.Symbol, r *ld.Reloc, sect
return true
}
func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
func archreloc(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, val *int64) bool {
if ld.Linkmode == ld.LinkExternal {
switch r.Type {
default:
......@@ -237,7 +238,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
// (https://sourceware.org/bugzilla/show_bug.cgi?id=18270). So
// we convert the adrp; ld64 + R_ARM64_GOTPCREL into adrp;
// add + R_ADDRARM64.
if !(r.Sym.Version != 0 || (r.Sym.Type&ld.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == ld.STEXT && ctxt.DynlinkingGo() {
if !(r.Sym.Version != 0 || (r.Sym.Type&sym.SHIDDEN != 0) || r.Sym.Attr.Local()) && r.Sym.Type == sym.STEXT && ctxt.DynlinkingGo() {
if o2&0xffc00000 != 0xf9400000 {
ld.Errorf(s, "R_ARM64_GOTPCREL against unexpected instruction %x", o2)
}
......@@ -261,7 +262,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
rs = rs.Outer
}
if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
if rs.Type != sym.SHOSTOBJ && rs.Type != sym.SDYNIMPORT && rs.Sect == nil {
ld.Errorf(s, "missing section for %s", rs.Name)
}
r.Xsym = rs
......@@ -367,7 +368,7 @@ func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) bool {
return false
}
func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
func archrelocvariant(ctxt *ld.Link, r *sym.Reloc, s *sym.Symbol, t int64) int64 {
log.Fatalf("unexpected relocation variant")
return -1
}
......
......@@ -33,6 +33,7 @@ package ld
import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
......@@ -105,7 +106,7 @@ func hostArchive(ctxt *Link, name string) {
var load []uint64
for _, s := range ctxt.Syms.Allsym {
for _, r := range s.R {
if r.Sym != nil && r.Sym.Type&SMASK == SXREF {
if r.Sym != nil && r.Sym.Type&sym.SMASK == sym.SXREF {
if off := armap[r.Sym.Name]; off != 0 && !loaded[off] {
load = append(load, off)
loaded[off] = true
......
This diff is collapsed.
......@@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"fmt"
"strings"
"unicode"
......@@ -112,13 +113,13 @@ func deadcode(ctxt *Link) {
// (When BuildmodeShared, always keep itablinks.)
for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.itablink.") {
s.Attr.Set(AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
s.Attr.Set(sym.AttrReachable, len(s.R) == 1 && s.R[0].Sym.Attr.Reachable())
}
}
}
// Remove dead text but keep file information (z symbols).
textp := make([]*Symbol, 0, len(ctxt.Textp))
textp := make([]*sym.Symbol, 0, len(ctxt.Textp))
for _, s := range ctxt.Textp {
if s.Attr.Reachable() {
textp = append(textp, s)
......@@ -132,11 +133,11 @@ func deadcode(ctxt *Link) {
// the reflect.method struct: mtyp, ifn, and tfn.
type methodref struct {
m methodsig
src *Symbol // receiver type symbol
r [3]*Reloc // R_METHODOFF relocations to fields of runtime.method
src *sym.Symbol // receiver type symbol
r [3]*sym.Reloc // R_METHODOFF relocations to fields of runtime.method
}
func (m methodref) ifn() *Symbol { return m.r[1].Sym }
func (m methodref) ifn() *sym.Symbol { return m.r[1].Sym }
func (m methodref) isExported() bool {
for _, r := range m.m {
......@@ -148,13 +149,13 @@ func (m methodref) isExported() bool {
// deadcodepass holds state for the deadcode flood fill.
type deadcodepass struct {
ctxt *Link
markQueue []*Symbol // symbols to flood fill in next pass
markQueue []*sym.Symbol // symbols to flood fill in next pass
ifaceMethod map[methodsig]bool // methods declared in reached interfaces
markableMethods []methodref // methods of reached types
reflectMethod bool
}
func (d *deadcodepass) cleanupReloc(r *Reloc) {
func (d *deadcodepass) cleanupReloc(r *sym.Reloc) {
if r.Sym.Attr.Reachable() {
r.Type = objabi.R_ADDROFF
} else {
......@@ -167,7 +168,7 @@ func (d *deadcodepass) cleanupReloc(r *Reloc) {
}
// mark appends a symbol to the mark queue for flood filling.
func (d *deadcodepass) mark(s, parent *Symbol) {
func (d *deadcodepass) mark(s, parent *sym.Symbol) {
if s == nil || s.Attr.Reachable() {
return
}
......@@ -181,7 +182,7 @@ func (d *deadcodepass) mark(s, parent *Symbol) {
}
fmt.Printf("%s -> %s\n", p, s.Name)
}
s.Attr |= AttrReachable
s.Attr |= sym.AttrReachable
s.Reachparent = parent
d.markQueue = append(d.markQueue, s)
}
......@@ -208,7 +209,7 @@ func (d *deadcodepass) init() {
// Mark all symbols defined in this library as reachable when
// building a shared library.
for _, s := range d.ctxt.Syms.Allsym {
if s.Type != 0 && s.Type != SDYNIMPORT {
if s.Type != 0 && s.Type != sym.SDYNIMPORT {
d.mark(s, nil)
}
}
......@@ -257,7 +258,7 @@ func (d *deadcodepass) flood() {
for len(d.markQueue) > 0 {
s := d.markQueue[0]
d.markQueue = d.markQueue[1:]
if s.Type == STEXT {
if s.Type == sym.STEXT {
if d.ctxt.Debugvlog > 1 {
d.ctxt.Logf("marktext %s\n", s.Name)
}
......
......@@ -8,6 +8,7 @@ import (
"bytes"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/elf"
"fmt"
)
......@@ -28,7 +29,7 @@ const (
tflagExtraStar = 1 << 1
)
func decodeReloc(s *Symbol, off int32) *Reloc {
func decodeReloc(s *sym.Symbol, off int32) *sym.Reloc {
for i := range s.R {
if s.R[i].Off == off {
return &s.R[i]
......@@ -37,7 +38,7 @@ func decodeReloc(s *Symbol, off int32) *Reloc {
return nil
}
func decodeRelocSym(s *Symbol, off int32) *Symbol {
func decodeRelocSym(s *sym.Symbol, off int32) *sym.Symbol {
r := decodeReloc(s, off)
if r == nil {
return nil
......@@ -64,27 +65,27 @@ func structfieldSize(arch *sys.Arch) int { return 3 * arch.PtrSize } // ru
func uncommonSize() int { return 4 + 2 + 2 + 4 + 4 } // runtime.uncommontype
// Type.commonType.kind
func decodetypeKind(arch *sys.Arch, s *Symbol) uint8 {
func decodetypeKind(arch *sys.Arch, s *sym.Symbol) uint8 {
return s.P[2*arch.PtrSize+7] & objabi.KindMask // 0x13 / 0x1f
}
// Type.commonType.kind
func decodetypeUsegcprog(arch *sys.Arch, s *Symbol) uint8 {
func decodetypeUsegcprog(arch *sys.Arch, s *sym.Symbol) uint8 {
return s.P[2*arch.PtrSize+7] & objabi.KindGCProg // 0x13 / 0x1f
}
// Type.commonType.size
func decodetypeSize(arch *sys.Arch, s *Symbol) int64 {
func decodetypeSize(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P, arch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.ptrdata
func decodetypePtrdata(arch *sys.Arch, s *Symbol) int64 {
func decodetypePtrdata(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[arch.PtrSize:], arch.PtrSize)) // 0x8 / 0x10
}
// Type.commonType.tflag
func decodetypeHasUncommon(arch *sys.Arch, s *Symbol) bool {
func decodetypeHasUncommon(arch *sys.Arch, s *sym.Symbol) bool {
return s.P[2*arch.PtrSize+4]&tflagUncommon != 0
}
......@@ -103,8 +104,8 @@ func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
}
// Type.commonType.gc
func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
if s.Type == SDYNIMPORT {
func decodetypeGcprog(ctxt *Link, s *sym.Symbol) []byte {
if s.Type == sym.SDYNIMPORT {
addr := decodetypeGcprogShlib(ctxt, s)
sect := findShlibSection(ctxt, s.File, addr)
if sect != nil {
......@@ -122,7 +123,7 @@ func decodetypeGcprog(ctxt *Link, s *Symbol) []byte {
return decodeRelocSym(s, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize)).P
}
func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 {
func decodetypeGcprogShlib(ctxt *Link, s *sym.Symbol) uint64 {
if ctxt.Arch.Family == sys.ARM64 {
for _, shlib := range ctxt.Shlibs {
if shlib.Path == s.File {
......@@ -134,8 +135,8 @@ func decodetypeGcprogShlib(ctxt *Link, s *Symbol) uint64 {
return decodeInuxi(ctxt.Arch, s.P[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
}
func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
if s.Type == SDYNIMPORT {
func decodetypeGcmask(ctxt *Link, s *sym.Symbol) []byte {
if s.Type == sym.SDYNIMPORT {
addr := decodetypeGcprogShlib(ctxt, s)
ptrdata := decodetypePtrdata(ctxt.Arch, s)
sect := findShlibSection(ctxt, s.File, addr)
......@@ -152,48 +153,48 @@ func decodetypeGcmask(ctxt *Link, s *Symbol) []byte {
}
// Type.ArrayType.elem and Type.SliceType.Elem
func decodetypeArrayElem(arch *sys.Arch, s *Symbol) *Symbol {
func decodetypeArrayElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
func decodetypeArrayLen(arch *sys.Arch, s *Symbol) int64 {
func decodetypeArrayLen(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
// Type.PtrType.elem
func decodetypePtrElem(arch *sys.Arch, s *Symbol) *Symbol {
func decodetypePtrElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
// Type.MapType.key, elem
func decodetypeMapKey(arch *sys.Arch, s *Symbol) *Symbol {
func decodetypeMapKey(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
func decodetypeMapValue(arch *sys.Arch, s *Symbol) *Symbol {
func decodetypeMapValue(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
}
// Type.ChanType.elem
func decodetypeChanElem(arch *sys.Arch, s *Symbol) *Symbol {
func decodetypeChanElem(arch *sys.Arch, s *sym.Symbol) *sym.Symbol {
return decodeRelocSym(s, int32(commonsize(arch))) // 0x1c / 0x30
}
// Type.FuncType.dotdotdot
func decodetypeFuncDotdotdot(arch *sys.Arch, s *Symbol) bool {
func decodetypeFuncDotdotdot(arch *sys.Arch, s *sym.Symbol) bool {
return uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2))&(1<<15) != 0
}
// Type.FuncType.inCount
func decodetypeFuncInCount(arch *sys.Arch, s *Symbol) int {
func decodetypeFuncInCount(arch *sys.Arch, s *sym.Symbol) int {
return int(decodeInuxi(arch, s.P[commonsize(arch):], 2))
}
func decodetypeFuncOutCount(arch *sys.Arch, s *Symbol) int {
func decodetypeFuncOutCount(arch *sys.Arch, s *sym.Symbol) int {
return int(uint16(decodeInuxi(arch, s.P[commonsize(arch)+2:], 2)) & (1<<15 - 1))
}
func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol {
func decodetypeFuncInType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
uadd := commonsize(arch) + 4
if arch.PtrSize == 8 {
uadd += 4
......@@ -204,16 +205,16 @@ func decodetypeFuncInType(arch *sys.Arch, s *Symbol, i int) *Symbol {
return decodeRelocSym(s, int32(uadd+i*arch.PtrSize))
}
func decodetypeFuncOutType(arch *sys.Arch, s *Symbol, i int) *Symbol {
func decodetypeFuncOutType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
return decodetypeFuncInType(arch, s, i+decodetypeFuncInCount(arch, s))
}
// Type.StructType.fields.Slice::length
func decodetypeStructFieldCount(arch *sys.Arch, s *Symbol) int {
func decodetypeStructFieldCount(arch *sys.Arch, s *sym.Symbol) int {
return int(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int {
func decodetypeStructFieldArrayOff(arch *sys.Arch, s *sym.Symbol, i int) int {
off := commonsize(arch) + 4*arch.PtrSize
if decodetypeHasUncommon(arch, s) {
off += uncommonSize()
......@@ -223,7 +224,7 @@ func decodetypeStructFieldArrayOff(arch *sys.Arch, s *Symbol, i int) int {
}
// decodetypeStr returns the contents of an rtype's str field (a nameOff).
func decodetypeStr(arch *sys.Arch, s *Symbol) string {
func decodetypeStr(arch *sys.Arch, s *sym.Symbol) string {
str := decodetypeName(s, 4*arch.PtrSize+8)
if s.P[2*arch.PtrSize+4]&tflagExtraStar != 0 {
return str[1:]
......@@ -232,7 +233,7 @@ func decodetypeStr(arch *sys.Arch, s *Symbol) string {
}
// decodetypeName decodes the name from a reflect.name.
func decodetypeName(s *Symbol, off int) string {
func decodetypeName(s *sym.Symbol, off int) string {
r := decodeReloc(s, int32(off))
if r == nil {
return ""
......@@ -243,27 +244,27 @@ func decodetypeName(s *Symbol, off int) string {
return string(data[3 : 3+namelen])
}
func decodetypeStructFieldName(arch *sys.Arch, s *Symbol, i int) string {
func decodetypeStructFieldName(arch *sys.Arch, s *sym.Symbol, i int) string {
off := decodetypeStructFieldArrayOff(arch, s, i)
return decodetypeName(s, off)
}
func decodetypeStructFieldType(arch *sys.Arch, s *Symbol, i int) *Symbol {
func decodetypeStructFieldType(arch *sys.Arch, s *sym.Symbol, i int) *sym.Symbol {
off := decodetypeStructFieldArrayOff(arch, s, i)
return decodeRelocSym(s, int32(off+arch.PtrSize))
}
func decodetypeStructFieldOffs(arch *sys.Arch, s *Symbol, i int) int64 {
func decodetypeStructFieldOffs(arch *sys.Arch, s *sym.Symbol, i int) int64 {
return decodetypeStructFieldOffsAnon(arch, s, i) >> 1
}
func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *Symbol, i int) int64 {
func decodetypeStructFieldOffsAnon(arch *sys.Arch, s *sym.Symbol, i int) int64 {
off := decodetypeStructFieldArrayOff(arch, s, i)
return int64(decodeInuxi(arch, s.P[off+2*arch.PtrSize:], arch.PtrSize))
}
// InterfaceType.methods.length
func decodetypeIfaceMethodCount(arch *sys.Arch, s *Symbol) int64 {
func decodetypeIfaceMethodCount(arch *sys.Arch, s *sym.Symbol) int64 {
return int64(decodeInuxi(arch, s.P[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
}
......@@ -290,7 +291,7 @@ const (
// the function type.
//
// Conveniently this is the layout of both runtime.method and runtime.imethod.
func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsig {
func decodeMethodSig(arch *sys.Arch, s *sym.Symbol, off, size, count int) []methodsig {
var buf bytes.Buffer
var methods []methodsig
for i := 0; i < count; i++ {
......@@ -322,7 +323,7 @@ func decodeMethodSig(arch *sys.Arch, s *Symbol, off, size, count int) []methodsi
return methods
}
func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig {
func decodeIfaceMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
if decodetypeKind(arch, s)&kindMask != kindInterface {
panic(fmt.Sprintf("symbol %q is not an interface", s.Name))
}
......@@ -339,7 +340,7 @@ func decodeIfaceMethods(arch *sys.Arch, s *Symbol) []methodsig {
return decodeMethodSig(arch, s, off, sizeofIMethod, numMethods)
}
func decodetypeMethods(arch *sys.Arch, s *Symbol) []methodsig {
func decodetypeMethods(arch *sys.Arch, s *sym.Symbol) []methodsig {
if !decodetypeHasUncommon(arch, s) {
panic(fmt.Sprintf("no methods on %q", s.Name))
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -10,6 +10,7 @@ import (
"bytes"
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/link/internal/sym"
"fmt"
"io"
"os"
......@@ -128,7 +129,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
var next string
var q string
var lib string
var s *Symbol
var s *sym.Symbol
p0 := ""
for ; p != ""; p = next {
......@@ -184,12 +185,12 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
remote, q = remote[:i], remote[i+1:]
}
s = ctxt.Syms.Lookup(local, 0)
if s.Type == 0 || s.Type == SXREF || s.Type == SHOSTOBJ {
if s.Type == 0 || s.Type == sym.SXREF || s.Type == sym.SHOSTOBJ {
s.Dynimplib = lib
s.Extname = remote
s.Dynimpvers = q
if s.Type != SHOSTOBJ {
s.Type = SDYNIMPORT
if s.Type != sym.SHOSTOBJ {
s.Type = sym.SDYNIMPORT
}
havedynamic = 1
}
......@@ -203,7 +204,7 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
}
local := f[1]
s = ctxt.Syms.Lookup(local, 0)
s.Type = SHOSTOBJ
s.Type = sym.SHOSTOBJ
s.Size = 0
continue
}
......@@ -248,9 +249,9 @@ func loadcgo(ctxt *Link, file string, pkg string, p string) {
}
if f[0] == "cgo_export_static" {
s.Attr |= AttrCgoExportStatic
s.Attr |= sym.AttrCgoExportStatic
} else {
s.Attr |= AttrCgoExportDynamic
s.Attr |= sym.AttrCgoExportDynamic
}
continue
}
......@@ -308,7 +309,7 @@ func adddynlib(ctxt *Link, lib string) {
}
}
func Adddynsym(ctxt *Link, s *Symbol) {
func Adddynsym(ctxt *Link, s *sym.Symbol) {
if s.Dynid >= 0 || Linkmode == LinkExternal {
return
}
......@@ -329,8 +330,8 @@ func fieldtrack(ctxt *Link) {
var buf bytes.Buffer
for _, s := range ctxt.Syms.Allsym {
if strings.HasPrefix(s.Name, "go.track.") {
s.Attr |= AttrSpecial // do not lay out in data segment
s.Attr |= AttrNotInSymbolTable
s.Attr |= sym.AttrSpecial // do not lay out in data segment
s.Attr |= sym.AttrNotInSymbolTable
if s.Attr.Reachable() {
buf.WriteString(s.Name[9:])
for p := s.Reachparent; p != nil; p = p.Reachparent {
......@@ -340,7 +341,7 @@ func fieldtrack(ctxt *Link) {
buf.WriteString("\n")
}
s.Type = SCONST
s.Type = sym.SCONST
s.Value = 0
}
}
......@@ -353,7 +354,7 @@ func fieldtrack(ctxt *Link) {
return
}
addstrdata(ctxt, *flagFieldTrack, buf.String())
s.Type = SDATA
s.Type = sym.SDATA
}
func (ctxt *Link) addexport() {
......
This diff is collapsed.
......@@ -4,6 +4,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"encoding/binary"
"fmt"
"io"
......@@ -92,7 +93,7 @@ type ldMachoSect struct {
flags uint32
res1 uint32
res2 uint32
sym *Symbol
sym *sym.Symbol
rel []ldMachoRel
}
......@@ -123,7 +124,7 @@ type ldMachoSym struct {
desc uint16
kind int8
value uint64
sym *Symbol
sym *sym.Symbol
}
type ldMachoDysymtab struct {
......@@ -428,15 +429,14 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
var sect *ldMachoSect
var rel *ldMachoRel
var rpi int
var s *Symbol
var s1 *Symbol
var outer *Symbol
var s *sym.Symbol
var s1 *sym.Symbol
var outer *sym.Symbol
var c *ldMachoCmd
var symtab *ldMachoSymtab
var dsymtab *ldMachoDysymtab
var sym *ldMachoSym
var r []Reloc
var rp *Reloc
var r []sym.Reloc
var rp *sym.Reloc
var name string
localSymVersion := ctxt.Syms.IncVersion()
......@@ -597,16 +597,16 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if sect.segname == "__TEXT" {
if sect.name == "__text" {
s.Type = STEXT
s.Type = sym.STEXT
} else {
s.Type = SRODATA
s.Type = sym.SRODATA
}
} else {
if sect.name == "__bss" {
s.Type = SNOPTRBSS
s.Type = sym.SNOPTRBSS
s.P = s.P[:0]
} else {
s.Type = SNOPTRDATA
s.Type = sym.SNOPTRDATA
}
}
......@@ -616,35 +616,35 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
// enter sub-symbols into symbol table.
// have to guess sizes from next symbol.
for i := 0; uint32(i) < symtab.nsym; i++ {
sym = &symtab.sym[i]
if sym.type_&N_STAB != 0 {
machsym := &symtab.sym[i]
if machsym.type_&N_STAB != 0 {
continue
}
// TODO: check sym->type against outer->type.
name = sym.name
name = machsym.name
if name[0] == '_' && name[1] != '\x00' {
name = name[1:]
}
v := 0
if sym.type_&N_EXT == 0 {
if machsym.type_&N_EXT == 0 {
v = localSymVersion
}
s = ctxt.Syms.Lookup(name, v)
if sym.type_&N_EXT == 0 {
s.Attr |= AttrDuplicateOK
if machsym.type_&N_EXT == 0 {
s.Attr |= sym.AttrDuplicateOK
}
sym.sym = s
if sym.sectnum == 0 { // undefined
machsym.sym = s
if machsym.sectnum == 0 { // undefined
continue
}
if uint32(sym.sectnum) > c.seg.nsect {
err = fmt.Errorf("reference to invalid section %d", sym.sectnum)
if uint32(machsym.sectnum) > c.seg.nsect {
err = fmt.Errorf("reference to invalid section %d", machsym.sectnum)
goto bad
}
sect = &c.seg.sect[sym.sectnum-1]
sect = &c.seg.sect[machsym.sectnum-1]
outer = sect.sym
if outer == nil {
err = fmt.Errorf("reference to invalid section %s/%s", sect.segname, sect.name)
......@@ -658,22 +658,22 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
Exitf("%s: duplicate symbol reference: %s in both %s and %s", pn, s.Name, s.Outer.Name, sect.sym.Name)
}
s.Type = outer.Type | SSUB
s.Type = outer.Type | sym.SSUB
s.Sub = outer.Sub
outer.Sub = s
s.Outer = outer
s.Value = int64(sym.value - sect.addr)
s.Value = int64(machsym.value - sect.addr)
if !s.Attr.CgoExportDynamic() {
s.Dynimplib = "" // satisfy dynimport
}
if outer.Type == STEXT {
if outer.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn)
}
s.Attr |= AttrExternal
s.Attr |= sym.AttrExternal
}
sym.sym = s
machsym.sym = s
}
// Sort outer lists by address, adding to textp.
......@@ -697,17 +697,17 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
}
}
if s.Type == STEXT {
if s.Type == sym.STEXT {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
for s1 = s.Sub; s1 != nil; s1 = s1.Sub {
if s1.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s1.Name)
}
s1.Attr |= AttrOnList
s1.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s1)
}
}
......@@ -724,7 +724,7 @@ func ldmacho(ctxt *Link, f *bio.Reader, pkg string, length int64, pn string) {
if sect.rel == nil {
continue
}
r = make([]Reloc, sect.nreloc)
r = make([]sym.Reloc, sect.nreloc)
rpi = 0
Reloc:
for j = 0; uint32(j) < sect.nreloc; j++ {
......
......@@ -8,6 +8,7 @@ import (
"cmd/internal/bio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/pe"
"errors"
"fmt"
......@@ -132,7 +133,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
localSymVersion := ctxt.Syms.IncVersion()
sectsyms := make(map[*pe.Section]*Symbol)
sectsyms := make(map[*pe.Section]*sym.Symbol)
sectdata := make(map[*pe.Section][]byte)
// Some input files are archives containing multiple of
......@@ -167,22 +168,22 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: //.rdata
s.Type = SRODATA
s.Type = sym.SRODATA
case IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.bss
s.Type = SNOPTRBSS
s.Type = sym.SNOPTRBSS
case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE: //.data
s.Type = SNOPTRDATA
s.Type = sym.SNOPTRDATA
case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: //.text
s.Type = STEXT
s.Type = sym.STEXT
default:
return fmt.Errorf("unexpected flags %#06x for PE section %s", sect.Characteristics, sect.Name)
}
if s.Type != SNOPTRBSS {
if s.Type != sym.SNOPTRBSS {
data, err := sect.Data()
if err != nil {
return err
......@@ -214,7 +215,7 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
continue
}
rs := make([]Reloc, rsect.NumberOfRelocations)
rs := make([]sym.Reloc, rsect.NumberOfRelocations)
for j, r := range rsect.Relocs {
rp := &rs[j]
if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
......@@ -314,11 +315,11 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
}
if pesym.SectionNumber == 0 { // extern
if s.Type == SDYNIMPORT {
if s.Type == sym.SDYNIMPORT {
s.Plt = -2 // flag for dynimport in PE object files.
}
if s.Type == SXREF && pesym.Value > 0 { // global data
s.Type = SNOPTRDATA
if s.Type == sym.SXREF && pesym.Value > 0 { // global data
s.Type = sym.SNOPTRDATA
s.Size = int64(pesym.Value)
}
......@@ -346,15 +347,15 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
sectsym := sectsyms[sect]
s.Sub = sectsym.Sub
sectsym.Sub = s
s.Type = sectsym.Type | SSUB
s.Type = sectsym.Type | sym.SSUB
s.Value = int64(pesym.Value)
s.Size = 4
s.Outer = sectsym
if sectsym.Type == STEXT {
if sectsym.Type == sym.STEXT {
if s.Attr.External() && !s.Attr.DuplicateOK() {
Errorf(s, "%s: duplicate symbol definition", pn)
}
s.Attr |= AttrExternal
s.Attr |= sym.AttrExternal
}
}
......@@ -368,17 +369,17 @@ func ldpeError(ctxt *Link, input *bio.Reader, pkg string, length int64, pn strin
if s.Sub != nil {
s.Sub = listsort(s.Sub)
}
if s.Type == STEXT {
if s.Type == sym.STEXT {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
for s = s.Sub; s != nil; s = s.Sub {
if s.Attr.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
s.Attr |= sym.AttrOnList
ctxt.Textp = append(ctxt.Textp, s)
}
}
......@@ -391,14 +392,14 @@ func issect(s *pe.COFFSymbol) bool {
return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
}
func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Section]*Symbol, localSymVersion int) (*Symbol, error) {
symname, err := sym.FullName(f.StringTable)
func readpesym(ctxt *Link, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]*sym.Symbol, localSymVersion int) (*sym.Symbol, error) {
symname, err := pesym.FullName(f.StringTable)
if err != nil {
return nil, err
}
var name string
if issect(sym) {
name = sectsyms[f.Sections[sym.SectionNumber-1]].Name
if issect(pesym) {
name = sectsyms[f.Sections[pesym.SectionNumber-1]].Name
} else {
name = symname
if strings.HasPrefix(name, "__imp_") {
......@@ -414,27 +415,27 @@ func readpesym(ctxt *Link, f *pe.File, sym *pe.COFFSymbol, sectsyms map[*pe.Sect
name = name[:i]
}
var s *Symbol
switch sym.Type {
var s *sym.Symbol
switch pesym.Type {
default:
return nil, fmt.Errorf("%s: invalid symbol type %d", symname, sym.Type)
return nil, fmt.Errorf("%s: invalid symbol type %d", symname, pesym.Type)
case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
switch sym.StorageClass {
switch pesym.StorageClass {
case IMAGE_SYM_CLASS_EXTERNAL: //global
s = ctxt.Syms.Lookup(name, 0)
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
s = ctxt.Syms.Lookup(name, localSymVersion)
s.Attr |= AttrDuplicateOK
s.Attr |= sym.AttrDuplicateOK
default:
return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, sym.StorageClass)
return nil, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)
}
}
if s != nil && s.Type == 0 && (sym.StorageClass != IMAGE_SYM_CLASS_STATIC || sym.Value != 0) {
s.Type = SXREF
if s != nil && s.Type == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
s.Type = sym.SXREF
}
if strings.HasPrefix(symname, "__imp_") {
s.Got = -2 // flag for __imp_
......
This diff is collapsed.
......@@ -34,124 +34,17 @@ import (
"bufio"
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"debug/elf"
"fmt"
)
// Attribute is a set of common symbol attributes.
type Attribute int16
const (
// AttrDuplicateOK marks a symbol that can be present in multiple object
// files.
AttrDuplicateOK Attribute = 1 << iota
// AttrExternal marks function symbols loaded from host object files.
AttrExternal
// AttrNoSplit marks functions that cannot split the stack; the linker
// cares because it checks that there are no call chains of nosplit
// functions that require more than StackLimit bytes (see
// lib.go:dostkcheck)
AttrNoSplit
// AttrReachable marks symbols that are transitively referenced from the
// entry points. Unreachable symbols are not written to the output.
AttrReachable
// AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
// by directives written by cgo (in response to //export directives in
// the source).
AttrCgoExportDynamic
AttrCgoExportStatic
// AttrSpecial marks symbols that do not have their address (i.e. Value)
// computed by the usual mechanism of data.go:dodata() &
// data.go:address().
AttrSpecial
// AttrStackCheck is used by dostkcheck to only check each NoSplit
// function's stack usage once.
AttrStackCheck
// AttrNotInSymbolTable marks symbols that are not written to the symbol table.
AttrNotInSymbolTable
// AttrOnList marks symbols that are on some list (such as the list of
// all text symbols, or one of the lists of data symbols) and is
// consulted to avoid bugs where a symbol is put on a list twice.
AttrOnList
// AttrLocal marks symbols that are only visible within the module
// (executable or shared library) being linked. Only relevant when
// dynamically linking Go code.
AttrLocal
// AttrReflectMethod marks certain methods from the reflect package that
// can be used to call arbitrary methods. If no symbol with this bit set
// is marked as reachable, more dead code elimination can be done.
AttrReflectMethod
// AttrMakeTypelink Amarks types that should be added to the typelink
// table. See typelinks.go:typelinks().
AttrMakeTypelink
// AttrShared marks symbols compiled with the -shared option.
AttrShared
// 14 attributes defined so far.
)
func (a Attribute) DuplicateOK() bool { return a&AttrDuplicateOK != 0 }
func (a Attribute) External() bool { return a&AttrExternal != 0 }
func (a Attribute) NoSplit() bool { return a&AttrNoSplit != 0 }
func (a Attribute) Reachable() bool { return a&AttrReachable != 0 }
func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
func (a Attribute) CgoExportStatic() bool { return a&AttrCgoExportStatic != 0 }
func (a Attribute) Special() bool { return a&AttrSpecial != 0 }
func (a Attribute) StackCheck() bool { return a&AttrStackCheck != 0 }
func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
func (a Attribute) Local() bool { return a&AttrLocal != 0 }
func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
func (a Attribute) MakeTypelink() bool { return a&AttrMakeTypelink != 0 }
func (a Attribute) Shared() bool { return a&AttrShared != 0 }
func (a Attribute) CgoExport() bool {
return a.CgoExportDynamic() || a.CgoExportStatic()
}
func (a *Attribute) Set(flag Attribute, value bool) {
if value {
*a |= flag
} else {
*a &^= flag
}
}
// Reloc is a relocation.
//
// The typical Reloc rewrites part of a symbol at offset Off to address Sym.
// A Reloc is stored in a slice on the Symbol it rewrites.
//
// Relocations are generated by the compiler as the type
// cmd/internal/obj.Reloc, which is encoded into the object file wire
// format and decoded by the linker into this type. A separate type is
// used to hold linker-specific state about the relocation.
//
// Some relocations are created by cmd/link.
type Reloc struct {
Off int32 // offset to rewrite
Siz uint8 // number of bytes to rewrite, 1, 2, or 4
Done bool // set to true when relocation is complete
Variant RelocVariant // variation on Type
Type objabi.RelocType // the relocation type
Add int64 // addend
Xadd int64 // addend passed to external linker
Sym *Symbol // symbol the relocation addresses
Xsym *Symbol // symbol passed to external linker
}
type Auto struct {
Asym *Symbol
Gotype *Symbol
Aoffset int32
Name int16
}
type Shlib struct {
Path string
Hash []byte
Deps []string
File *elf.File
gcdataAddresses map[*Symbol]uint64
gcdataAddresses map[*sym.Symbol]uint64
}
// Link holds the context for writing object code from a compiler
......@@ -159,7 +52,7 @@ type Shlib struct {
type Link struct {
Out *OutBuf
Syms *Symbols
Syms *sym.Symbols
Arch *sys.Arch
Debugvlog int
......@@ -167,20 +60,20 @@ type Link struct {
Loaded bool // set after all inputs have been loaded as symbols
Tlsg *Symbol
Tlsg *sym.Symbol
Libdir []string
Library []*Library
LibraryByPkg map[string]*Library
Shlibs []Shlib
Tlsoffset int
Textp []*Symbol
Filesyms []*Symbol
Moduledata *Symbol
Textp []*sym.Symbol
Filesyms []*sym.Symbol
Moduledata *sym.Symbol
PackageFile map[string]string
PackageShlib map[string]string
tramps []*Symbol // trampolines
tramps []*sym.Symbol // trampolines
}
// The smallest possible offset from the hardware stack pointer to a local
......@@ -214,8 +107,8 @@ type Library struct {
hash string
importStrings []string
imports []*Library
textp []*Symbol // text symbols defined in this library
dupTextSyms []*Symbol // dupok text symbols defined in this library
textp []*sym.Symbol // text symbols defined in this library
dupTextSyms []*sym.Symbol // dupok text symbols defined in this library
}
func (l Library) String() string {
......@@ -233,35 +126,8 @@ func (l *Library) addImports(ctxt *Link, pn string) {
l.importStrings = nil
}
type FuncInfo struct {
Args int32
Locals int32
Autom []Auto
Pcsp Pcdata
Pcfile Pcdata
Pcline Pcdata
Pcinline Pcdata
Pcdata []Pcdata
Funcdata []*Symbol
Funcdataoff []int64
File []*Symbol
InlTree []InlinedCall
}
// InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
type InlinedCall struct {
Parent int32 // index of parent in InlTree
File *Symbol // file of the inlined call
Line int32 // line number of the inlined call
Func *Symbol // function that was inlined
}
type Pcdata struct {
P []byte
}
type Pciter struct {
d Pcdata
d sym.Pcdata
p []byte
pc uint32
nextpc uint32
......@@ -270,66 +136,3 @@ type Pciter struct {
start int
done int
}
// RelocVariant is a linker-internal variation on a relocation.
type RelocVariant uint8
const (
RV_NONE RelocVariant = iota
RV_POWER_LO
RV_POWER_HI
RV_POWER_HA
RV_POWER_DS
// RV_390_DBL is a s390x-specific relocation variant that indicates that
// the value to be placed into the relocatable field should first be
// divided by 2.
RV_390_DBL
RV_CHECK_OVERFLOW RelocVariant = 1 << 7
RV_TYPE_MASK RelocVariant = RV_CHECK_OVERFLOW - 1
)
func RelocName(arch *sys.Arch, r objabi.RelocType) string {
// We didn't have some relocation types at Go1.4.
// Uncomment code when we include those in bootstrap code.
switch {
case r >= 512: // Mach-O
// nr := (r - 512)>>1
// switch ctxt.Arch.Family {
// case sys.AMD64:
// return macho.RelocTypeX86_64(nr).String()
// case sys.ARM:
// return macho.RelocTypeARM(nr).String()
// case sys.ARM64:
// return macho.RelocTypeARM64(nr).String()
// case sys.I386:
// return macho.RelocTypeGeneric(nr).String()
// default:
// panic("unreachable")
// }
case r >= 256: // ELF
nr := r - 256
switch arch.Family {
case sys.AMD64:
return elf.R_X86_64(nr).String()
case sys.ARM:
return elf.R_ARM(nr).String()
case sys.ARM64:
return elf.R_AARCH64(nr).String()
case sys.I386:
return elf.R_386(nr).String()
case sys.MIPS, sys.MIPS64:
// return elf.R_MIPS(nr).String()
case sys.PPC64:
// return elf.R_PPC64(nr).String()
case sys.S390X:
// return elf.R_390(nr).String()
default:
panic("unreachable")
}
}
return r.String()
}
......@@ -7,6 +7,7 @@ package ld
import (
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
"sort"
"strings"
)
......@@ -169,7 +170,7 @@ const (
var nkind [NumSymKind]int
var sortsym []*Symbol
var sortsym []*sym.Symbol
var nsortsym int
......@@ -346,32 +347,32 @@ func (ctxt *Link) domacho() {
// empirically, string table must begin with " \x00".
s := ctxt.Syms.Lookup(".machosymstr", 0)
s.Type = SMACHOSYMSTR
s.Attr |= AttrReachable
s.Type = sym.SMACHOSYMSTR
s.Attr |= sym.AttrReachable
s.AddUint8(' ')
s.AddUint8('\x00')
s = ctxt.Syms.Lookup(".machosymtab", 0)
s.Type = SMACHOSYMTAB
s.Attr |= AttrReachable
s.Type = sym.SMACHOSYMTAB
s.Attr |= sym.AttrReachable
if Linkmode != LinkExternal {
s := ctxt.Syms.Lookup(".plt", 0) // will be __symbol_stub
s.Type = SMACHOPLT
s.Attr |= AttrReachable
s.Type = sym.SMACHOPLT
s.Attr |= sym.AttrReachable
s = ctxt.Syms.Lookup(".got", 0) // will be __nl_symbol_ptr
s.Type = SMACHOGOT
s.Attr |= AttrReachable
s.Type = sym.SMACHOGOT
s.Attr |= sym.AttrReachable
s.Align = 4
s = ctxt.Syms.Lookup(".linkedit.plt", 0) // indirect table for .plt
s.Type = SMACHOINDIRECTPLT
s.Attr |= AttrReachable
s.Type = sym.SMACHOINDIRECTPLT
s.Attr |= sym.AttrReachable
s = ctxt.Syms.Lookup(".linkedit.got", 0) // indirect table for .got
s.Type = SMACHOINDIRECTGOT
s.Attr |= AttrReachable
s.Type = sym.SMACHOINDIRECTGOT
s.Attr |= sym.AttrReachable
}
}
......@@ -396,7 +397,7 @@ func machoadddynlib(lib string) {
dylib = append(dylib, lib)
}
func machoshbits(ctxt *Link, mseg *MachoSeg, sect *Section, segname string) {
func machoshbits(ctxt *Link, mseg *MachoSeg, sect *sym.Section, segname string) {
buf := "__" + strings.Replace(sect.Name[1:], ".", "_", -1)
var msect *MachoSect
......@@ -647,8 +648,8 @@ func Asmbmacho(ctxt *Link) {
}
}
func symkind(s *Symbol) int {
if s.Type == SDYNIMPORT {
func symkind(s *sym.Symbol) int {
if s.Type == sym.SDYNIMPORT {
return SymKindUndef
}
if s.Attr.CgoExport() {
......@@ -657,7 +658,7 @@ func symkind(s *Symbol) int {
return SymKindLocal
}
func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, gotype *Symbol) {
func addsym(ctxt *Link, s *sym.Symbol, name string, type_ SymbolType, addr int64, gotype *sym.Symbol) {
if s == nil {
return
}
......@@ -678,7 +679,7 @@ func addsym(ctxt *Link, s *Symbol, name string, type_ SymbolType, addr int64, go
nsortsym++
}
type machoscmp []*Symbol
type machoscmp []*sym.Symbol
func (x machoscmp) Len() int {
return len(x)
......@@ -704,7 +705,7 @@ func (x machoscmp) Less(i, j int) bool {
func machogenasmsym(ctxt *Link) {
genasmsym(ctxt, addsym)
for _, s := range ctxt.Syms.Allsym {
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
if s.Attr.Reachable() {
addsym(ctxt, s, "", DataSym, 0, nil)
}
......@@ -717,10 +718,10 @@ func machosymorder(ctxt *Link) {
// So we sort them here and pre-allocate dynid for them
// See https://golang.org/issue/4029
for i := 0; i < len(dynexp); i++ {
dynexp[i].Attr |= AttrReachable
dynexp[i].Attr |= sym.AttrReachable
}
machogenasmsym(ctxt)
sortsym = make([]*Symbol, nsortsym)
sortsym = make([]*sym.Symbol, nsortsym)
nsortsym = 0
machogenasmsym(ctxt)
sort.Sort(machoscmp(sortsym[:nsortsym]))
......@@ -733,7 +734,7 @@ func machosymorder(ctxt *Link) {
//
// When dynamically linking, all non-local variables and plugin-exported
// symbols need to be exported.
func machoShouldExport(ctxt *Link, s *Symbol) bool {
func machoShouldExport(ctxt *Link, s *sym.Symbol) bool {
if !ctxt.DynlinkingGo() || s.Attr.Local() {
return false
}
......@@ -752,7 +753,7 @@ func machoShouldExport(ctxt *Link, s *Symbol) bool {
if strings.HasPrefix(s.Name, "go.link.pkghash") {
return true
}
return s.Type >= SELFSECT // only writable sections
return s.Type >= sym.SELFSECT // only writable sections
}
func machosymtab(ctxt *Link) {
......@@ -780,11 +781,11 @@ func machosymtab(ctxt *Link) {
// replace "·" as ".", because DTrace cannot handle it.
Addstring(symstr, strings.Replace(s.Extname, "·", ".", -1))
if s.Type == SDYNIMPORT || s.Type == SHOSTOBJ {
if s.Type == sym.SDYNIMPORT || s.Type == sym.SHOSTOBJ {
symtab.AddUint8(0x01) // type N_EXT, external symbol
symtab.AddUint8(0) // no section
symtab.AddUint16(ctxt.Arch, 0) // desc
symtab.addUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
symtab.AddUintXX(ctxt.Arch, 0, ctxt.Arch.PtrSize) // no value
} else {
if s.Attr.CgoExport() || export {
symtab.AddUint8(0x0f)
......@@ -802,7 +803,7 @@ func machosymtab(ctxt *Link) {
symtab.AddUint8(uint8(o.Sect.Extnum))
}
symtab.AddUint16(ctxt.Arch, 0) // desc
symtab.addUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
symtab.AddUintXX(ctxt.Arch, uint64(Symaddr(s)), ctxt.Arch.PtrSize)
}
}
}
......@@ -889,7 +890,7 @@ func Domacholink(ctxt *Link) int64 {
return Rnd(int64(size), int64(*FlagRound))
}
func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
func machorelocsect(ctxt *Link, sect *sym.Section, syms []*sym.Symbol) {
// If main section has no bits, nothing to relocate.
if sect.Vaddr >= sect.Seg.Vaddr+sect.Seg.Filelen {
return
......@@ -907,27 +908,27 @@ func machorelocsect(ctxt *Link, sect *Section, syms []*Symbol) {
}
eaddr := int32(sect.Vaddr + sect.Length)
for _, sym := range syms {
if !sym.Attr.Reachable() {
for _, s := range syms {
if !s.Attr.Reachable() {
continue
}
if sym.Value >= int64(eaddr) {
if s.Value >= int64(eaddr) {
break
}
for ri := 0; ri < len(sym.R); ri++ {
r := &sym.R[ri]
for ri := 0; ri < len(s.R); ri++ {
r := &s.R[ri]
if r.Done {
continue
}
if r.Xsym == nil {
Errorf(sym, "missing xsym in relocation")
Errorf(s, "missing xsym in relocation")
continue
}
if !r.Xsym.Attr.Reachable() {
Errorf(sym, "unreachable reloc %d (%s) target %v", r.Type, RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
Errorf(s, "unreachable reloc %d (%s) target %v", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Xsym.Name)
}
if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, sym, r, int64(uint64(sym.Value+int64(r.Off))-sect.Vaddr)) {
Errorf(sym, "unsupported obj reloc %d (%s)/%d to %s", r.Type, RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
if !Thearch.Machoreloc1(ctxt.Arch, ctxt.Out, s, r, int64(uint64(s.Value+int64(r.Off))-sect.Vaddr)) {
Errorf(s, "unsupported obj reloc %d (%s)/%d to %s", r.Type, sym.RelocName(ctxt.Arch, r.Type), r.Siz, r.Sym.Name)
}
}
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// Code generated by "stringer -type=SymKind"; DO NOT EDIT.
package ld
package sym
import "fmt"
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment