mirror of
https://github.com/golang/go
synced 2024-11-18 11:44:45 -07:00
[dev.link] cmd/link: combine decodesym.go and decodesym2.go
And remove "2" from some function names. Change-Id: Ibf1089970d849a42f53976064ceb9ade20bf6eba Reviewed-on: https://go-review.googlesource.com/c/go/+/231017 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
parent
2a33f5368a
commit
4048fb8780
@ -1123,7 +1123,7 @@ func (p *GCProg2) AddSym(s loader.Sym) {
|
||||
sval := ldr.SymValue(s)
|
||||
if decodetypeUsegcprog(p.ctxt.Arch, typData) == 0 {
|
||||
// Copy pointers from mask into program.
|
||||
mask := decodetypeGcmask2(p.ctxt, typ)
|
||||
mask := decodetypeGcmask(p.ctxt, typ)
|
||||
for i := int64(0); i < nptr; i++ {
|
||||
if (mask[i/8]>>uint(i%8))&1 != 0 {
|
||||
p.w.Ptr(sval/ptrsize + i)
|
||||
@ -1133,7 +1133,7 @@ func (p *GCProg2) AddSym(s loader.Sym) {
|
||||
}
|
||||
|
||||
// Copy program.
|
||||
prog := decodetypeGcprog2(p.ctxt, typ)
|
||||
prog := decodetypeGcprog(p.ctxt, typ)
|
||||
p.w.ZeroUntil(sval / ptrsize)
|
||||
p.w.Append(prog[4:], nptr)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ type deadcodePass struct {
|
||||
wq workQueue
|
||||
|
||||
ifaceMethod map[methodsig]bool // methods declared in reached interfaces
|
||||
markableMethods []methodref2 // methods of reached types
|
||||
markableMethods []methodref // methods of reached types
|
||||
reflectSeen bool // whether we have seen a reflect method call
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ func (d *deadcodePass) flood() {
|
||||
if isgotype {
|
||||
p := d.ldr.Data(symIdx)
|
||||
if len(p) != 0 && decodetypeKind(d.ctxt.Arch, p)&kindMask == kindInterface {
|
||||
for _, sig := range d.decodeIfaceMethods2(d.ldr, d.ctxt.Arch, symIdx, &relocs) {
|
||||
for _, sig := range d.decodeIfaceMethods(d.ldr, d.ctxt.Arch, symIdx, &relocs) {
|
||||
if d.ctxt.Debugvlog > 1 {
|
||||
d.ctxt.Logf("reached iface method: %s\n", sig)
|
||||
}
|
||||
@ -129,7 +129,7 @@ func (d *deadcodePass) flood() {
|
||||
}
|
||||
}
|
||||
|
||||
var methods []methodref2
|
||||
var methods []methodref
|
||||
for i := 0; i < relocs.Count(); i++ {
|
||||
r := relocs.At2(i)
|
||||
t := r.Type()
|
||||
@ -140,7 +140,7 @@ func (d *deadcodePass) flood() {
|
||||
if i+2 >= relocs.Count() {
|
||||
panic("expect three consecutive R_METHODOFF relocs")
|
||||
}
|
||||
methods = append(methods, methodref2{src: symIdx, r: i})
|
||||
methods = append(methods, methodref{src: symIdx, r: i})
|
||||
i += 2
|
||||
continue
|
||||
}
|
||||
@ -174,7 +174,7 @@ func (d *deadcodePass) flood() {
|
||||
// Decode runtime type information for type methods
|
||||
// to help work out which methods can be called
|
||||
// dynamically via interfaces.
|
||||
methodsigs := d.decodetypeMethods2(d.ldr, d.ctxt.Arch, symIdx, &relocs)
|
||||
methodsigs := d.decodetypeMethods(d.ldr, d.ctxt.Arch, symIdx, &relocs)
|
||||
if len(methods) != len(methodsigs) {
|
||||
panic(fmt.Sprintf("%q has %d method relocations for %d methods", d.ldr.SymName(symIdx), len(methods), len(methodsigs)))
|
||||
}
|
||||
@ -206,7 +206,7 @@ func (d *deadcodePass) mark(symIdx, parent loader.Sym) {
|
||||
}
|
||||
}
|
||||
|
||||
func (d *deadcodePass) markMethod(m methodref2) {
|
||||
func (d *deadcodePass) markMethod(m methodref) {
|
||||
relocs := d.ldr.Relocs(m.src)
|
||||
d.mark(relocs.At2(m.r).Sym(), m.src)
|
||||
d.mark(relocs.At2(m.r+1).Sym(), m.src)
|
||||
@ -305,16 +305,16 @@ func deadcode(ctxt *Link) {
|
||||
}
|
||||
}
|
||||
|
||||
// methodref2 holds the relocations from a receiver type symbol to its
|
||||
// methodref holds the relocations from a receiver type symbol to its
|
||||
// method. There are three relocations, one for each of the fields in
|
||||
// the reflect.method struct: mtyp, ifn, and tfn.
|
||||
type methodref2 struct {
|
||||
type methodref struct {
|
||||
m methodsig
|
||||
src loader.Sym // receiver type symbol
|
||||
r int // the index of R_METHODOFF relocations
|
||||
}
|
||||
|
||||
func (m methodref2) isExported() bool {
|
||||
func (m methodref) isExported() bool {
|
||||
for _, r := range m.m {
|
||||
return unicode.IsUpper(r)
|
||||
}
|
||||
@ -327,12 +327,12 @@ func (m methodref2) isExported() bool {
|
||||
// the function type.
|
||||
//
|
||||
// Conveniently this is the layout of both runtime.method and runtime.imethod.
|
||||
func (d *deadcodePass) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, off, size, count int) []methodsig {
|
||||
func (d *deadcodePass) decodeMethodSig(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, off, size, count int) []methodsig {
|
||||
var buf bytes.Buffer
|
||||
var methods []methodsig
|
||||
for i := 0; i < count; i++ {
|
||||
buf.WriteString(decodetypeName2(ldr, symIdx, relocs, off))
|
||||
mtypSym := decodeRelocSym2(ldr, symIdx, relocs, int32(off+4))
|
||||
buf.WriteString(decodetypeName(ldr, symIdx, relocs, off))
|
||||
mtypSym := decodeRelocSym(ldr, symIdx, relocs, int32(off+4))
|
||||
// FIXME: add some sort of caching here, since we may see some of the
|
||||
// same symbols over time for param types.
|
||||
mrelocs := ldr.Relocs(mtypSym)
|
||||
@ -344,7 +344,7 @@ func (d *deadcodePass) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, symI
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
a := decodetypeFuncInType2(ldr, arch, mtypSym, &mrelocs, i)
|
||||
a := decodetypeFuncInType(ldr, arch, mtypSym, &mrelocs, i)
|
||||
buf.WriteString(ldr.SymName(a))
|
||||
}
|
||||
buf.WriteString(") (")
|
||||
@ -353,7 +353,7 @@ func (d *deadcodePass) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, symI
|
||||
if i > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
a := decodetypeFuncOutType2(ldr, arch, mtypSym, &mrelocs, i)
|
||||
a := decodetypeFuncOutType(ldr, arch, mtypSym, &mrelocs, i)
|
||||
buf.WriteString(ldr.SymName(a))
|
||||
}
|
||||
buf.WriteRune(')')
|
||||
@ -365,12 +365,12 @@ func (d *deadcodePass) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, symI
|
||||
return methods
|
||||
}
|
||||
|
||||
func (d *deadcodePass) decodeIfaceMethods2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
||||
func (d *deadcodePass) decodeIfaceMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
||||
p := ldr.Data(symIdx)
|
||||
if decodetypeKind(arch, p)&kindMask != kindInterface {
|
||||
panic(fmt.Sprintf("symbol %q is not an interface", ldr.SymName(symIdx)))
|
||||
}
|
||||
rel := decodeReloc2(ldr, symIdx, relocs, int32(commonsize(arch)+arch.PtrSize))
|
||||
rel := decodeReloc(ldr, symIdx, relocs, int32(commonsize(arch)+arch.PtrSize))
|
||||
s := rel.Sym()
|
||||
if s == 0 {
|
||||
return nil
|
||||
@ -381,10 +381,10 @@ func (d *deadcodePass) decodeIfaceMethods2(ldr *loader.Loader, arch *sys.Arch, s
|
||||
off := int(rel.Add()) // array of reflect.imethod values
|
||||
numMethods := int(decodetypeIfaceMethodCount(arch, p))
|
||||
sizeofIMethod := 4 + 4
|
||||
return d.decodeMethodSig2(ldr, arch, symIdx, relocs, off, sizeofIMethod, numMethods)
|
||||
return d.decodeMethodSig(ldr, arch, symIdx, relocs, off, sizeofIMethod, numMethods)
|
||||
}
|
||||
|
||||
func (d *deadcodePass) decodetypeMethods2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
||||
func (d *deadcodePass) decodetypeMethods(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs) []methodsig {
|
||||
p := ldr.Data(symIdx)
|
||||
if !decodetypeHasUncommon(arch, p) {
|
||||
panic(fmt.Sprintf("no methods on %q", ldr.SymName(symIdx)))
|
||||
@ -415,5 +415,5 @@ func (d *deadcodePass) decodetypeMethods2(ldr *loader.Loader, arch *sys.Arch, sy
|
||||
moff := int(decodeInuxi(arch, p[off+4+2+2:], 4))
|
||||
off += moff // offset to array of reflect.method values
|
||||
const sizeofMethod = 4 * 4 // sizeof reflect.method in program
|
||||
return d.decodeMethodSig2(ldr, arch, symIdx, relocs, off, sizeofMethod, mcount)
|
||||
return d.decodeMethodSig(ldr, arch, symIdx, relocs, off, sizeofMethod, mcount)
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ package ld
|
||||
import (
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/sys"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
"debug/elf"
|
||||
)
|
||||
|
||||
@ -69,27 +71,6 @@ func decodetypeHasUncommon(arch *sys.Arch, p []byte) bool {
|
||||
return p[2*arch.PtrSize+4]&tflagUncommon != 0
|
||||
}
|
||||
|
||||
// Find the elf.Section of a given shared library that contains a given address.
|
||||
func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
|
||||
for _, shlib := range ctxt.Shlibs {
|
||||
if shlib.Path == path {
|
||||
for _, sect := range shlib.File.Sections {
|
||||
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
|
||||
return sect
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodetypeGcprogShlib(ctxt *Link, data []byte) uint64 {
|
||||
if ctxt.Arch.Family == sys.ARM64 {
|
||||
return 0
|
||||
}
|
||||
return decodeInuxi(ctxt.Arch, data[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
|
||||
}
|
||||
|
||||
// Type.FuncType.dotdotdot
|
||||
func decodetypeFuncDotdotdot(arch *sys.Arch, p []byte) bool {
|
||||
return uint16(decodeInuxi(arch, p[commonsize(arch)+2:], 2))&(1<<15) != 0
|
||||
@ -125,3 +106,181 @@ const (
|
||||
kindStruct = 25
|
||||
kindMask = (1 << 5) - 1
|
||||
)
|
||||
|
||||
func decodeReloc(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Reloc2 {
|
||||
for j := 0; j < relocs.Count(); j++ {
|
||||
rel := relocs.At2(j)
|
||||
if rel.Off() == off {
|
||||
return rel
|
||||
}
|
||||
}
|
||||
return loader.Reloc2{}
|
||||
}
|
||||
|
||||
func decodeRelocSym(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Sym {
|
||||
return decodeReloc(ldr, symIdx, relocs, off).Sym()
|
||||
}
|
||||
|
||||
// decodetypeName decodes the name from a reflect.name.
|
||||
func decodetypeName(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) string {
|
||||
r := decodeRelocSym(ldr, symIdx, relocs, int32(off))
|
||||
if r == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
data := ldr.Data(r)
|
||||
namelen := int(uint16(data[1])<<8 | uint16(data[2]))
|
||||
return string(data[3 : 3+namelen])
|
||||
}
|
||||
|
||||
func decodetypeFuncInType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
|
||||
uadd := commonsize(arch) + 4
|
||||
if arch.PtrSize == 8 {
|
||||
uadd += 4
|
||||
}
|
||||
if decodetypeHasUncommon(arch, ldr.Data(symIdx)) {
|
||||
uadd += uncommonSize()
|
||||
}
|
||||
return decodeRelocSym(ldr, symIdx, relocs, int32(uadd+i*arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeFuncOutType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
|
||||
return decodetypeFuncInType(ldr, arch, symIdx, relocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
|
||||
}
|
||||
|
||||
func decodetypeArrayElem(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeArrayLen(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int64 {
|
||||
data := ldr.Data(symIdx)
|
||||
return int64(decodeInuxi(arch, data[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeChanElem(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeMapKey(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeMapValue(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
|
||||
}
|
||||
|
||||
func decodetypePtrElem(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeStructFieldCount(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int {
|
||||
data := ldr.Data(symIdx)
|
||||
return int(decodeInuxi(arch, data[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeStructFieldArrayOff(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int {
|
||||
data := ldr.Data(symIdx)
|
||||
off := commonsize(arch) + 4*arch.PtrSize
|
||||
if decodetypeHasUncommon(arch, data) {
|
||||
off += uncommonSize()
|
||||
}
|
||||
off += i * structfieldSize(arch)
|
||||
return off
|
||||
}
|
||||
|
||||
func decodetypeStructFieldName(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) string {
|
||||
off := decodetypeStructFieldArrayOff(ldr, arch, symIdx, i)
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodetypeName(ldr, symIdx, &relocs, off)
|
||||
}
|
||||
|
||||
func decodetypeStructFieldType(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) loader.Sym {
|
||||
off := decodetypeStructFieldArrayOff(ldr, arch, symIdx, i)
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym(ldr, symIdx, &relocs, int32(off+arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeStructFieldOffsAnon(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int64 {
|
||||
off := decodetypeStructFieldArrayOff(ldr, arch, symIdx, i)
|
||||
data := ldr.Data(symIdx)
|
||||
return int64(decodeInuxi(arch, data[off+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
// decodetypeStr returns the contents of an rtype's str field (a nameOff).
|
||||
func decodetypeStr(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) string {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
str := decodetypeName(ldr, symIdx, &relocs, 4*arch.PtrSize+8)
|
||||
data := ldr.Data(symIdx)
|
||||
if data[2*arch.PtrSize+4]&tflagExtraStar != 0 {
|
||||
return str[1:]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func decodetypeGcmask(ctxt *Link, s loader.Sym) []byte {
|
||||
if ctxt.loader.SymType(s) == sym.SDYNIMPORT {
|
||||
symData := ctxt.loader.Data(s)
|
||||
addr := decodetypeGcprogShlib(ctxt, symData)
|
||||
ptrdata := decodetypePtrdata(ctxt.Arch, symData)
|
||||
sect := findShlibSection(ctxt, ctxt.loader.SymPkg(s), addr)
|
||||
if sect != nil {
|
||||
r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
|
||||
sect.ReadAt(r, int64(addr-sect.Addr))
|
||||
return r
|
||||
}
|
||||
Exitf("cannot find gcmask for %s", ctxt.loader.SymName(s))
|
||||
return nil
|
||||
}
|
||||
relocs := ctxt.loader.Relocs(s)
|
||||
mask := decodeRelocSym(ctxt.loader, s, &relocs, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
|
||||
return ctxt.loader.Data(mask)
|
||||
}
|
||||
|
||||
// Type.commonType.gc
|
||||
func decodetypeGcprog(ctxt *Link, s loader.Sym) []byte {
|
||||
if ctxt.loader.SymType(s) == sym.SDYNIMPORT {
|
||||
symData := ctxt.loader.Data(s)
|
||||
addr := decodetypeGcprogShlib(ctxt, symData)
|
||||
sect := findShlibSection(ctxt, ctxt.loader.SymPkg(s), addr)
|
||||
if sect != nil {
|
||||
// A gcprog is a 4-byte uint32 indicating length, followed by
|
||||
// the actual program.
|
||||
progsize := make([]byte, 4)
|
||||
sect.ReadAt(progsize, int64(addr-sect.Addr))
|
||||
progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
|
||||
sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
|
||||
return append(progsize, progbytes...)
|
||||
}
|
||||
Exitf("cannot find gcmask for %s", ctxt.loader.SymName(s))
|
||||
return nil
|
||||
}
|
||||
relocs := ctxt.loader.Relocs(s)
|
||||
rs := decodeRelocSym(ctxt.loader, s, &relocs, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
|
||||
return ctxt.loader.Data(rs)
|
||||
}
|
||||
|
||||
// Find the elf.Section of a given shared library that contains a given address.
|
||||
func findShlibSection(ctxt *Link, path string, addr uint64) *elf.Section {
|
||||
for _, shlib := range ctxt.Shlibs {
|
||||
if shlib.Path == path {
|
||||
for _, sect := range shlib.File.Sections {
|
||||
if sect.Addr <= addr && addr <= sect.Addr+sect.Size {
|
||||
return sect
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodetypeGcprogShlib(ctxt *Link, data []byte) uint64 {
|
||||
if ctxt.Arch.Family == sys.ARM64 {
|
||||
return 0
|
||||
}
|
||||
return decodeInuxi(ctxt.Arch, data[2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize):], ctxt.Arch.PtrSize)
|
||||
}
|
||||
|
@ -1,174 +0,0 @@
|
||||
// Copyright 2019 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/sys"
|
||||
"cmd/link/internal/loader"
|
||||
"cmd/link/internal/sym"
|
||||
)
|
||||
|
||||
// This file contains utilities to decode type.* symbols, for
|
||||
// loader.Sym symbols (uses new loader interfaces).
|
||||
|
||||
// At some point we'll want to migrate the contents of this file
|
||||
// to decodesym.go once the rouetines there have been decprecated + removed.
|
||||
|
||||
func decodeReloc2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Reloc2 {
|
||||
for j := 0; j < relocs.Count(); j++ {
|
||||
rel := relocs.At2(j)
|
||||
if rel.Off() == off {
|
||||
return rel
|
||||
}
|
||||
}
|
||||
return loader.Reloc2{}
|
||||
}
|
||||
|
||||
func decodeRelocSym2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int32) loader.Sym {
|
||||
return decodeReloc2(ldr, symIdx, relocs, off).Sym()
|
||||
}
|
||||
|
||||
// decodetypeName2 decodes the name from a reflect.name.
|
||||
func decodetypeName2(ldr *loader.Loader, symIdx loader.Sym, relocs *loader.Relocs, off int) string {
|
||||
r := decodeRelocSym2(ldr, symIdx, relocs, int32(off))
|
||||
if r == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
data := ldr.Data(r)
|
||||
namelen := int(uint16(data[1])<<8 | uint16(data[2]))
|
||||
return string(data[3 : 3+namelen])
|
||||
}
|
||||
|
||||
func decodetypeFuncInType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
|
||||
uadd := commonsize(arch) + 4
|
||||
if arch.PtrSize == 8 {
|
||||
uadd += 4
|
||||
}
|
||||
if decodetypeHasUncommon(arch, ldr.Data(symIdx)) {
|
||||
uadd += uncommonSize()
|
||||
}
|
||||
return decodeRelocSym2(ldr, symIdx, relocs, int32(uadd+i*arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeFuncOutType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, relocs *loader.Relocs, i int) loader.Sym {
|
||||
return decodetypeFuncInType2(ldr, arch, symIdx, relocs, i+decodetypeFuncInCount(arch, ldr.Data(symIdx)))
|
||||
}
|
||||
|
||||
func decodetypeArrayElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeArrayLen2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int64 {
|
||||
data := ldr.Data(symIdx)
|
||||
return int64(decodeInuxi(arch, data[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeChanElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeMapKey2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeMapValue2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))+int32(arch.PtrSize)) // 0x20 / 0x38
|
||||
}
|
||||
|
||||
func decodetypePtrElem2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) loader.Sym {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(commonsize(arch))) // 0x1c / 0x30
|
||||
}
|
||||
|
||||
func decodetypeStructFieldCount2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) int {
|
||||
data := ldr.Data(symIdx)
|
||||
return int(decodeInuxi(arch, data[commonsize(arch)+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeStructFieldArrayOff2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int {
|
||||
data := ldr.Data(symIdx)
|
||||
off := commonsize(arch) + 4*arch.PtrSize
|
||||
if decodetypeHasUncommon(arch, data) {
|
||||
off += uncommonSize()
|
||||
}
|
||||
off += i * structfieldSize(arch)
|
||||
return off
|
||||
}
|
||||
|
||||
func decodetypeStructFieldName2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) string {
|
||||
off := decodetypeStructFieldArrayOff2(ldr, arch, symIdx, i)
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodetypeName2(ldr, symIdx, &relocs, off)
|
||||
}
|
||||
|
||||
func decodetypeStructFieldType2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) loader.Sym {
|
||||
off := decodetypeStructFieldArrayOff2(ldr, arch, symIdx, i)
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
return decodeRelocSym2(ldr, symIdx, &relocs, int32(off+arch.PtrSize))
|
||||
}
|
||||
|
||||
func decodetypeStructFieldOffsAnon2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym, i int) int64 {
|
||||
off := decodetypeStructFieldArrayOff2(ldr, arch, symIdx, i)
|
||||
data := ldr.Data(symIdx)
|
||||
return int64(decodeInuxi(arch, data[off+2*arch.PtrSize:], arch.PtrSize))
|
||||
}
|
||||
|
||||
// decodetypeStr2 returns the contents of an rtype's str field (a nameOff).
|
||||
func decodetypeStr2(ldr *loader.Loader, arch *sys.Arch, symIdx loader.Sym) string {
|
||||
relocs := ldr.Relocs(symIdx)
|
||||
str := decodetypeName2(ldr, symIdx, &relocs, 4*arch.PtrSize+8)
|
||||
data := ldr.Data(symIdx)
|
||||
if data[2*arch.PtrSize+4]&tflagExtraStar != 0 {
|
||||
return str[1:]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
func decodetypeGcmask2(ctxt *Link, s loader.Sym) []byte {
|
||||
if ctxt.loader.SymType(s) == sym.SDYNIMPORT {
|
||||
symData := ctxt.loader.Data(s)
|
||||
addr := decodetypeGcprogShlib(ctxt, symData)
|
||||
ptrdata := decodetypePtrdata(ctxt.Arch, symData)
|
||||
sect := findShlibSection(ctxt, ctxt.loader.SymPkg(s), addr)
|
||||
if sect != nil {
|
||||
r := make([]byte, ptrdata/int64(ctxt.Arch.PtrSize))
|
||||
sect.ReadAt(r, int64(addr-sect.Addr))
|
||||
return r
|
||||
}
|
||||
Exitf("cannot find gcmask for %s", ctxt.loader.SymName(s))
|
||||
return nil
|
||||
}
|
||||
relocs := ctxt.loader.Relocs(s)
|
||||
mask := decodeRelocSym2(ctxt.loader, s, &relocs, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
|
||||
return ctxt.loader.Data(mask)
|
||||
}
|
||||
|
||||
// Type.commonType.gc
|
||||
func decodetypeGcprog2(ctxt *Link, s loader.Sym) []byte {
|
||||
if ctxt.loader.SymType(s) == sym.SDYNIMPORT {
|
||||
symData := ctxt.loader.Data(s)
|
||||
addr := decodetypeGcprogShlib(ctxt, symData)
|
||||
sect := findShlibSection(ctxt, ctxt.loader.SymPkg(s), addr)
|
||||
if sect != nil {
|
||||
// A gcprog is a 4-byte uint32 indicating length, followed by
|
||||
// the actual program.
|
||||
progsize := make([]byte, 4)
|
||||
sect.ReadAt(progsize, int64(addr-sect.Addr))
|
||||
progbytes := make([]byte, ctxt.Arch.ByteOrder.Uint32(progsize))
|
||||
sect.ReadAt(progbytes, int64(addr-sect.Addr+4))
|
||||
return append(progsize, progbytes...)
|
||||
}
|
||||
Exitf("cannot find gcmask for %s", ctxt.loader.SymName(s))
|
||||
return nil
|
||||
}
|
||||
relocs := ctxt.loader.Relocs(s)
|
||||
rs := decodeRelocSym2(ctxt.loader, s, &relocs, 2*int32(ctxt.Arch.PtrSize)+8+1*int32(ctxt.Arch.PtrSize))
|
||||
return ctxt.loader.Data(rs)
|
||||
}
|
@ -576,18 +576,18 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_ARRAYTYPE, name, 0)
|
||||
typedefdie = d.dotypedef(&dwtypes, gotype, name, die)
|
||||
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
|
||||
s := decodetypeArrayElem2(d.ldr, d.arch, gotype)
|
||||
s := decodetypeArrayElem(d.ldr, d.arch, gotype)
|
||||
d.newrefattr(die, dwarf.DW_AT_type, d.defgotype(s))
|
||||
fld := d.newdie(die, dwarf.DW_ABRV_ARRAYRANGE, "range", 0)
|
||||
|
||||
// use actual length not upper bound; correct for 0-length arrays.
|
||||
newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetypeArrayLen2(d.ldr, d.arch, gotype), 0)
|
||||
newattr(fld, dwarf.DW_AT_count, dwarf.DW_CLS_CONSTANT, decodetypeArrayLen(d.ldr, d.arch, gotype), 0)
|
||||
|
||||
d.newrefattr(fld, dwarf.DW_AT_type, d.uintptrInfoSym)
|
||||
|
||||
case objabi.KindChan:
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_CHANTYPE, name, 0)
|
||||
s := decodetypeChanElem2(d.ldr, d.arch, gotype)
|
||||
s := decodetypeChanElem(d.ldr, d.arch, gotype)
|
||||
d.newrefattr(die, dwarf.DW_AT_go_elem, d.defgotype(s))
|
||||
// Save elem type for synthesizechantypes. We could synthesize here
|
||||
// but that would change the order of DIEs we output.
|
||||
@ -602,7 +602,7 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
relocs := d.ldr.Relocs(gotype)
|
||||
nfields := decodetypeFuncInCount(d.arch, data)
|
||||
for i := 0; i < nfields; i++ {
|
||||
s := decodetypeFuncInType2(d.ldr, d.arch, gotype, &relocs, i)
|
||||
s := decodetypeFuncInType(d.ldr, d.arch, gotype, &relocs, i)
|
||||
sn := d.ldr.SymName(s)
|
||||
fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, sn[5:], 0)
|
||||
d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
|
||||
@ -613,7 +613,7 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
}
|
||||
nfields = decodetypeFuncOutCount(d.arch, data)
|
||||
for i := 0; i < nfields; i++ {
|
||||
s := decodetypeFuncOutType2(d.ldr, d.arch, gotype, &relocs, i)
|
||||
s := decodetypeFuncOutType(d.ldr, d.arch, gotype, &relocs, i)
|
||||
sn := d.ldr.SymName(s)
|
||||
fld := d.newdie(die, dwarf.DW_ABRV_FUNCTYPEPARAM, sn[5:], 0)
|
||||
d.newrefattr(fld, dwarf.DW_AT_type, d.defptrto(d.defgotype(s)))
|
||||
@ -634,9 +634,9 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
|
||||
case objabi.KindMap:
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_MAPTYPE, name, 0)
|
||||
s := decodetypeMapKey2(d.ldr, d.arch, gotype)
|
||||
s := decodetypeMapKey(d.ldr, d.arch, gotype)
|
||||
d.newrefattr(die, dwarf.DW_AT_go_key, d.defgotype(s))
|
||||
s = decodetypeMapValue2(d.ldr, d.arch, gotype)
|
||||
s = decodetypeMapValue(d.ldr, d.arch, gotype)
|
||||
d.newrefattr(die, dwarf.DW_AT_go_elem, d.defgotype(s))
|
||||
// Save gotype for use in synthesizemaptypes. We could synthesize here,
|
||||
// but that would change the order of the DIEs.
|
||||
@ -645,14 +645,14 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
case objabi.KindPtr:
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_PTRTYPE, name, 0)
|
||||
typedefdie = d.dotypedef(&dwtypes, gotype, name, die)
|
||||
s := decodetypePtrElem2(d.ldr, d.arch, gotype)
|
||||
s := decodetypePtrElem(d.ldr, d.arch, gotype)
|
||||
d.newrefattr(die, dwarf.DW_AT_type, d.defgotype(s))
|
||||
|
||||
case objabi.KindSlice:
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_SLICETYPE, name, 0)
|
||||
typedefdie = d.dotypedef(&dwtypes, gotype, name, die)
|
||||
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
|
||||
s := decodetypeArrayElem2(d.ldr, d.arch, gotype)
|
||||
s := decodetypeArrayElem(d.ldr, d.arch, gotype)
|
||||
elem := d.defgotype(s)
|
||||
d.newrefattr(die, dwarf.DW_AT_go_elem, elem)
|
||||
|
||||
@ -664,17 +664,17 @@ func (d *dwctxt2) newtype(gotype loader.Sym) *dwarf.DWDie {
|
||||
die = d.newdie(&dwtypes, dwarf.DW_ABRV_STRUCTTYPE, name, 0)
|
||||
typedefdie = d.dotypedef(&dwtypes, gotype, name, die)
|
||||
newattr(die, dwarf.DW_AT_byte_size, dwarf.DW_CLS_CONSTANT, bytesize, 0)
|
||||
nfields := decodetypeStructFieldCount2(d.ldr, d.arch, gotype)
|
||||
nfields := decodetypeStructFieldCount(d.ldr, d.arch, gotype)
|
||||
for i := 0; i < nfields; i++ {
|
||||
f := decodetypeStructFieldName2(d.ldr, d.arch, gotype, i)
|
||||
s := decodetypeStructFieldType2(d.ldr, d.arch, gotype, i)
|
||||
f := decodetypeStructFieldName(d.ldr, d.arch, gotype, i)
|
||||
s := decodetypeStructFieldType(d.ldr, d.arch, gotype, i)
|
||||
if f == "" {
|
||||
sn := d.ldr.SymName(s)
|
||||
f = sn[5:] // skip "type."
|
||||
}
|
||||
fld := d.newdie(die, dwarf.DW_ABRV_STRUCTFIELD, f, 0)
|
||||
d.newrefattr(fld, dwarf.DW_AT_type, d.defgotype(s))
|
||||
offsetAnon := decodetypeStructFieldOffsAnon2(d.ldr, d.arch, gotype, i)
|
||||
offsetAnon := decodetypeStructFieldOffsAnon(d.ldr, d.arch, gotype, i)
|
||||
newmemberoffsetattr(fld, int32(offsetAnon>>1))
|
||||
if offsetAnon&1 != 0 { // is embedded field
|
||||
newattr(fld, dwarf.DW_AT_go_embedded_field, dwarf.DW_CLS_FLAG, 1, 0)
|
||||
@ -874,8 +874,8 @@ func (d *dwctxt2) synthesizemaptypes(ctxt *Link, die *dwarf.DWDie) {
|
||||
continue
|
||||
}
|
||||
gotype := loader.Sym(getattr(die, dwarf.DW_AT_type).Data.(dwSym))
|
||||
keytype := decodetypeMapKey2(d.ldr, d.arch, gotype)
|
||||
valtype := decodetypeMapValue2(d.ldr, d.arch, gotype)
|
||||
keytype := decodetypeMapKey(d.ldr, d.arch, gotype)
|
||||
valtype := decodetypeMapValue(d.ldr, d.arch, gotype)
|
||||
keydata := d.ldr.Data(keytype)
|
||||
valdata := d.ldr.Data(valtype)
|
||||
keysize, valsize := decodetypeSize(d.arch, keydata), decodetypeSize(d.arch, valdata)
|
||||
|
@ -30,7 +30,7 @@ func (ctxt *Link) typelink() {
|
||||
typelinks := byTypeStr{}
|
||||
for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
|
||||
if ldr.AttrReachable(s) && ldr.IsTypelink(s) {
|
||||
typelinks = append(typelinks, typelinkSortKey{decodetypeStr2(ldr, ctxt.Arch, s), s})
|
||||
typelinks = append(typelinks, typelinkSortKey{decodetypeStr(ldr, ctxt.Arch, s), s})
|
||||
}
|
||||
}
|
||||
sort.Sort(typelinks)
|
||||
|
Loading…
Reference in New Issue
Block a user