2017-09-30 15:06:44 +00:00
|
|
|
// Copyright 2017 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.
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
package sym
|
2017-09-30 15:06:44 +00:00
|
|
|
|
|
|
|
|
import (
|
2018-10-26 13:53:02 -04:00
|
|
|
"cmd/internal/obj"
|
2017-09-30 15:06:44 +00:00
|
|
|
"cmd/internal/objabi"
|
|
|
|
|
"cmd/internal/sys"
|
|
|
|
|
"debug/elf"
|
|
|
|
|
"fmt"
|
|
|
|
|
"log"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Symbol is an entry in the symbol table.
|
|
|
|
|
type Symbol struct {
|
|
|
|
|
Name string
|
|
|
|
|
Type SymKind
|
|
|
|
|
Version int16
|
|
|
|
|
Attr Attribute
|
|
|
|
|
Dynid int32
|
|
|
|
|
Align int32
|
|
|
|
|
Elfsym int32
|
|
|
|
|
LocalElfsym int32
|
|
|
|
|
Value int64
|
|
|
|
|
Size int64
|
2018-07-18 10:19:35 -04:00
|
|
|
Sub *Symbol
|
|
|
|
|
Outer *Symbol
|
|
|
|
|
Gotype *Symbol
|
2018-12-04 07:58:18 -08:00
|
|
|
File string // actually package!
|
2018-07-18 10:19:35 -04:00
|
|
|
auxinfo *AuxSymbol
|
|
|
|
|
Sect *Section
|
|
|
|
|
FuncInfo *FuncInfo
|
|
|
|
|
Lib *Library // Package defining this symbol
|
2017-09-30 15:06:44 +00:00
|
|
|
// P contains the raw symbol data.
|
|
|
|
|
P []byte
|
|
|
|
|
R []Reloc
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-17 11:02:57 -04:00
|
|
|
// AuxSymbol contains less-frequently used sym.Symbol fields.
|
|
|
|
|
type AuxSymbol struct {
|
|
|
|
|
extname string
|
2018-06-28 16:10:19 -04:00
|
|
|
dynimplib string
|
|
|
|
|
dynimpvers string
|
2018-07-17 14:38:34 -04:00
|
|
|
localentry uint8
|
2018-07-17 15:36:30 -04:00
|
|
|
plt int32
|
|
|
|
|
got int32
|
2018-07-18 10:19:35 -04:00
|
|
|
// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
|
|
|
|
|
// is not set for symbols defined by the packages being linked or by symbols
|
|
|
|
|
// read by ldelf (and so is left as elf.STT_NOTYPE).
|
|
|
|
|
elftype elf.SymType
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
2018-10-19 17:42:11 -04:00
|
|
|
const (
|
2018-10-26 13:53:02 -04:00
|
|
|
SymVerABI0 = 0
|
|
|
|
|
SymVerABIInternal = 1
|
|
|
|
|
SymVerStatic = 10 // Minimum version used by static (file-local) syms
|
2018-10-19 17:42:11 -04:00
|
|
|
)
|
|
|
|
|
|
2018-10-26 13:53:02 -04:00
|
|
|
func ABIToVersion(abi obj.ABI) int {
|
|
|
|
|
switch abi {
|
|
|
|
|
case obj.ABI0:
|
|
|
|
|
return SymVerABI0
|
|
|
|
|
case obj.ABIInternal:
|
|
|
|
|
return SymVerABIInternal
|
|
|
|
|
}
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
|
cmd/link: fix confusing error on unresolved symbol
Currently, if an assembly file includes a static reference to an
undefined symbol, and another package also has an undefined reference
to that symbol, the linker can report an error like:
x: relocation target zero not defined for ABI0 (but is defined for ABI0)
Since the symbol is referenced in another package, the code in
ErrorUnresolved that looks for alternative ABI symbols finds that
symbol in the symbol table, but doesn't check that it's actually
defined, which is where the "but is defined for ABI0" comes from. The
"not defined for ABI0" is because ErrorUnresolved failed to turn the
static symbol's version back into an ABI, and it happened to print the
zero value for an ABI.
This CL fixes both of these problems. It explicitly maps the
relocation version back to an ABI and detects if it can't be mapped
back (e.g., because it's a static reference). Then, if it finds a
symbol with a different ABI in the symbol table, it checks to make
sure it's a definition, and not simply an unresolved reference.
Fixes #29852.
Change-Id: Ice45cc41c1907919ce5750f74588e8047eaa888c
Reviewed-on: https://go-review.googlesource.com/c/159518
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-01-27 21:03:32 -05:00
|
|
|
func VersionToABI(v int) (obj.ABI, bool) {
|
|
|
|
|
switch v {
|
|
|
|
|
case SymVerABI0:
|
|
|
|
|
return obj.ABI0, true
|
|
|
|
|
case SymVerABIInternal:
|
|
|
|
|
return obj.ABIInternal, true
|
|
|
|
|
}
|
|
|
|
|
return ^obj.ABI(0), false
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
func (s *Symbol) String() string {
|
|
|
|
|
if s.Version == 0 {
|
|
|
|
|
return s.Name
|
|
|
|
|
}
|
|
|
|
|
return fmt.Sprintf("%s<%d>", s.Name, s.Version)
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-19 17:42:11 -04:00
|
|
|
func (s *Symbol) IsFileLocal() bool {
|
|
|
|
|
return s.Version >= SymVerStatic
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
func (s *Symbol) ElfsymForReloc() int32 {
|
|
|
|
|
// If putelfsym created a local version of this symbol, use that in all
|
|
|
|
|
// relocations.
|
|
|
|
|
if s.LocalElfsym != 0 {
|
|
|
|
|
return s.LocalElfsym
|
|
|
|
|
} else {
|
|
|
|
|
return s.Elfsym
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) Len() int64 {
|
|
|
|
|
return s.Size
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) Grow(siz int64) {
|
|
|
|
|
if int64(int(siz)) != siz {
|
|
|
|
|
log.Fatalf("symgrow size %d too long", siz)
|
|
|
|
|
}
|
|
|
|
|
if int64(len(s.P)) >= siz {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if cap(s.P) < int(siz) {
|
|
|
|
|
p := make([]byte, 2*(siz+1))
|
|
|
|
|
s.P = append(p[:0], s.P...)
|
|
|
|
|
}
|
|
|
|
|
s.P = s.P[:siz]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddBytes(bytes []byte) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
s.P = append(s.P, bytes...)
|
|
|
|
|
s.Size = int64(len(s.P))
|
|
|
|
|
|
|
|
|
|
return s.Size
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddUint8(v uint8) int64 {
|
|
|
|
|
off := s.Size
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
s.Size++
|
|
|
|
|
s.P = append(s.P, v)
|
|
|
|
|
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
|
2017-10-04 17:54:04 -04:00
|
|
|
return s.AddUintXX(arch, uint64(v), 2)
|
2017-09-30 15:06:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
|
2017-10-04 17:54:04 -04:00
|
|
|
return s.AddUintXX(arch, uint64(v), 4)
|
2017-09-30 15:06:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
|
2017-10-04 17:54:04 -04:00
|
|
|
return s.AddUintXX(arch, v, 8)
|
2017-09-30 15:06:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
|
2017-10-04 17:54:04 -04:00
|
|
|
return s.AddUintXX(arch, v, arch.PtrSize)
|
2017-09-30 15:06:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
|
|
|
|
|
return s.setUintXX(arch, r, uint64(v), 1)
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-04 07:58:18 -08:00
|
|
|
func (s *Symbol) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
|
|
|
|
|
return s.setUintXX(arch, r, uint64(v), 2)
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
|
|
|
|
|
return s.setUintXX(arch, r, uint64(v), 4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
|
|
|
|
|
return s.setUintXX(arch, r, v, int64(arch.PtrSize))
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-02 17:26:49 -04:00
|
|
|
func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
|
2017-09-30 15:06:44 +00:00
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
i := s.Size
|
|
|
|
|
s.Size += int64(arch.PtrSize)
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
r := s.AddRel()
|
|
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(i)
|
|
|
|
|
r.Siz = uint8(arch.PtrSize)
|
2019-04-02 17:26:49 -04:00
|
|
|
r.Type = typ
|
2017-09-30 15:06:44 +00:00
|
|
|
r.Add = add
|
|
|
|
|
return i + int64(r.Siz)
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-02 17:26:49 -04:00
|
|
|
func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
|
|
|
return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
|
|
|
return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-30 15:06:44 +00:00
|
|
|
func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
i := s.Size
|
|
|
|
|
s.Size += 4
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
r := s.AddRel()
|
|
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(i)
|
|
|
|
|
r.Add = add
|
|
|
|
|
r.Type = objabi.R_PCREL
|
|
|
|
|
r.Siz = 4
|
|
|
|
|
if arch.Family == sys.S390X {
|
|
|
|
|
r.Variant = RV_390_DBL
|
|
|
|
|
}
|
|
|
|
|
return i + int64(r.Siz)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
|
|
|
|
|
return s.AddAddrPlus(arch, t, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
if off+int64(arch.PtrSize) > s.Size {
|
|
|
|
|
s.Size = off + int64(arch.PtrSize)
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r := s.AddRel()
|
|
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(off)
|
|
|
|
|
r.Siz = uint8(arch.PtrSize)
|
|
|
|
|
r.Type = objabi.R_ADDR
|
|
|
|
|
r.Add = add
|
|
|
|
|
return off + int64(r.Siz)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
|
|
|
|
|
return s.SetAddrPlus(arch, off, t, 0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
i := s.Size
|
|
|
|
|
s.Size += int64(arch.PtrSize)
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
r := s.AddRel()
|
|
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(i)
|
|
|
|
|
r.Siz = uint8(arch.PtrSize)
|
|
|
|
|
r.Type = objabi.R_SIZE
|
|
|
|
|
return i + int64(r.Siz)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
i := s.Size
|
|
|
|
|
s.Size += 4
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
r := s.AddRel()
|
|
|
|
|
r.Sym = t
|
|
|
|
|
r.Off = int32(i)
|
|
|
|
|
r.Siz = 4
|
|
|
|
|
r.Type = objabi.R_ADDR
|
|
|
|
|
r.Add = add
|
|
|
|
|
return i + int64(r.Siz)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) AddRel() *Reloc {
|
|
|
|
|
s.R = append(s.R, Reloc{})
|
|
|
|
|
return &s.R[len(s.R)-1]
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
|
2017-09-30 15:06:44 +00:00
|
|
|
off := s.Size
|
|
|
|
|
s.setUintXX(arch, off, v, int64(wid))
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
|
|
|
|
|
if s.Type == 0 {
|
|
|
|
|
s.Type = SDATA
|
|
|
|
|
}
|
|
|
|
|
s.Attr |= AttrReachable
|
|
|
|
|
if s.Size < off+wid {
|
|
|
|
|
s.Size = off + wid
|
|
|
|
|
s.Grow(s.Size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch wid {
|
|
|
|
|
case 1:
|
|
|
|
|
s.P[off] = uint8(v)
|
|
|
|
|
case 2:
|
|
|
|
|
arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
|
|
|
|
|
case 4:
|
|
|
|
|
arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
|
|
|
|
|
case 8:
|
|
|
|
|
arch.ByteOrder.PutUint64(s.P[off:], v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return off + wid
|
|
|
|
|
}
|
2017-10-04 17:54:04 -04:00
|
|
|
|
2018-07-17 11:02:57 -04:00
|
|
|
func (s *Symbol) makeAuxInfo() {
|
|
|
|
|
if s.auxinfo == nil {
|
2018-07-17 15:36:30 -04:00
|
|
|
s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
|
2018-07-17 11:02:57 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) Extname() string {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
return s.Name
|
|
|
|
|
}
|
|
|
|
|
return s.auxinfo.extname
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetExtname(n string) {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
if s.Name == n {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.makeAuxInfo()
|
|
|
|
|
}
|
|
|
|
|
s.auxinfo.extname = n
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-28 16:10:19 -04:00
|
|
|
func (s *Symbol) Dynimplib() string {
|
2018-07-17 11:02:57 -04:00
|
|
|
if s.auxinfo == nil {
|
2018-06-28 16:10:19 -04:00
|
|
|
return ""
|
|
|
|
|
}
|
2018-07-17 11:02:57 -04:00
|
|
|
return s.auxinfo.dynimplib
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) Dynimpvers() string {
|
2018-07-17 11:02:57 -04:00
|
|
|
if s.auxinfo == nil {
|
2018-06-28 16:10:19 -04:00
|
|
|
return ""
|
|
|
|
|
}
|
2018-07-17 11:02:57 -04:00
|
|
|
return s.auxinfo.dynimpvers
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetDynimplib(lib string) {
|
2018-07-17 11:02:57 -04:00
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
s.makeAuxInfo()
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
2018-07-17 11:02:57 -04:00
|
|
|
s.auxinfo.dynimplib = lib
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetDynimpvers(vers string) {
|
2018-07-17 11:02:57 -04:00
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
s.makeAuxInfo()
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
2018-07-17 11:02:57 -04:00
|
|
|
s.auxinfo.dynimpvers = vers
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) ResetDyninfo() {
|
2018-07-17 11:02:57 -04:00
|
|
|
if s.auxinfo != nil {
|
|
|
|
|
s.auxinfo.dynimplib = ""
|
|
|
|
|
s.auxinfo.dynimpvers = ""
|
|
|
|
|
}
|
2018-06-28 16:10:19 -04:00
|
|
|
}
|
|
|
|
|
|
2018-07-17 14:38:34 -04:00
|
|
|
func (s *Symbol) Localentry() uint8 {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
return 0
|
|
|
|
|
}
|
|
|
|
|
return s.auxinfo.localentry
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetLocalentry(val uint8) {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
if val != 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.makeAuxInfo()
|
|
|
|
|
}
|
|
|
|
|
s.auxinfo.localentry = val
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-17 15:36:30 -04:00
|
|
|
func (s *Symbol) Plt() int32 {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
return s.auxinfo.plt
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetPlt(val int32) {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
if val == -1 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.makeAuxInfo()
|
|
|
|
|
}
|
|
|
|
|
s.auxinfo.plt = val
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) Got() int32 {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
return -1
|
|
|
|
|
}
|
|
|
|
|
return s.auxinfo.got
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetGot(val int32) {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
if val == -1 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.makeAuxInfo()
|
|
|
|
|
}
|
|
|
|
|
s.auxinfo.got = val
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-18 10:19:35 -04:00
|
|
|
func (s *Symbol) ElfType() elf.SymType {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
return elf.STT_NOTYPE
|
|
|
|
|
}
|
|
|
|
|
return s.auxinfo.elftype
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s *Symbol) SetElfType(val elf.SymType) {
|
|
|
|
|
if s.auxinfo == nil {
|
|
|
|
|
if val == elf.STT_NOTYPE {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
s.makeAuxInfo()
|
|
|
|
|
}
|
|
|
|
|
s.auxinfo.elftype = val
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-06 11:53:52 -04:00
|
|
|
// SortSub sorts a linked-list (by Sub) of *Symbol by Value.
|
|
|
|
|
// Used for sub-symbols when loading host objects (see e.g. ldelf.go).
|
|
|
|
|
func SortSub(l *Symbol) *Symbol {
|
|
|
|
|
if l == nil || l.Sub == nil {
|
|
|
|
|
return l
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
l1 := l
|
|
|
|
|
l2 := l
|
|
|
|
|
for {
|
|
|
|
|
l2 = l2.Sub
|
|
|
|
|
if l2 == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
l2 = l2.Sub
|
|
|
|
|
if l2 == nil {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
l1 = l1.Sub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
l2 = l1.Sub
|
|
|
|
|
l1.Sub = nil
|
|
|
|
|
l1 = SortSub(l)
|
|
|
|
|
l2 = SortSub(l2)
|
|
|
|
|
|
|
|
|
|
/* set up lead element */
|
|
|
|
|
if l1.Value < l2.Value {
|
|
|
|
|
l = l1
|
|
|
|
|
l1 = l1.Sub
|
|
|
|
|
} else {
|
|
|
|
|
l = l2
|
|
|
|
|
l2 = l2.Sub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
le := l
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
if l1 == nil {
|
|
|
|
|
for l2 != nil {
|
|
|
|
|
le.Sub = l2
|
|
|
|
|
le = l2
|
|
|
|
|
l2 = l2.Sub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
le.Sub = nil
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if l2 == nil {
|
|
|
|
|
for l1 != nil {
|
|
|
|
|
le.Sub = l1
|
|
|
|
|
le = l1
|
|
|
|
|
l1 = l1.Sub
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if l1.Value < l2.Value {
|
|
|
|
|
le.Sub = l1
|
|
|
|
|
le = l1
|
|
|
|
|
l1 = l1.Sub
|
|
|
|
|
} else {
|
|
|
|
|
le.Sub = l2
|
|
|
|
|
le = l2
|
|
|
|
|
l2 = l2.Sub
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
le.Sub = nil
|
|
|
|
|
return l
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-04 17:54:04 -04:00
|
|
|
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 {
|
2018-12-04 07:58:18 -08:00
|
|
|
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
|
|
|
|
|
ParentPC int32 // PC of the instruction just before the inlined body (offset from function start)
|
2017-10-04 17:54:04 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Pcdata struct {
|
|
|
|
|
P []byte
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type Auto struct {
|
|
|
|
|
Asym *Symbol
|
|
|
|
|
Gotype *Symbol
|
|
|
|
|
Aoffset int32
|
|
|
|
|
Name int16
|
|
|
|
|
}
|