github.com/zxy12/go_duplicate_112_new@v0.0.0-20200807091221-747231827200/src/cmd/link/internal/sym/symbol.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sym
     6  
     7  import (
     8  	"cmd/internal/obj"
     9  	"cmd/internal/objabi"
    10  	"cmd/internal/sys"
    11  	"debug/elf"
    12  	"fmt"
    13  	"log"
    14  )
    15  
    16  // Symbol is an entry in the symbol table.
    17  type Symbol struct {
    18  	Name        string
    19  	Type        SymKind
    20  	Version     int16
    21  	Attr        Attribute
    22  	Dynid       int32
    23  	Align       int32
    24  	Elfsym      int32
    25  	LocalElfsym int32
    26  	Value       int64
    27  	Size        int64
    28  	Sub         *Symbol
    29  	Outer       *Symbol
    30  	Gotype      *Symbol
    31  	File        string // actually package!
    32  	auxinfo     *AuxSymbol
    33  	Sect        *Section
    34  	FuncInfo    *FuncInfo
    35  	Lib         *Library // Package defining this symbol
    36  	// P contains the raw symbol data.
    37  	P []byte
    38  	R []Reloc
    39  }
    40  
    41  // AuxSymbol contains less-frequently used sym.Symbol fields.
    42  type AuxSymbol struct {
    43  	extname    string
    44  	dynimplib  string
    45  	dynimpvers string
    46  	localentry uint8
    47  	plt        int32
    48  	got        int32
    49  	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
    50  	// is not set for symbols defined by the packages being linked or by symbols
    51  	// read by ldelf (and so is left as elf.STT_NOTYPE).
    52  	elftype elf.SymType
    53  }
    54  
    55  const (
    56  	SymVerABI0        = 0
    57  	SymVerABIInternal = 1
    58  	SymVerStatic      = 10 // Minimum version used by static (file-local) syms
    59  )
    60  
    61  func ABIToVersion(abi obj.ABI) int {
    62  	switch abi {
    63  	case obj.ABI0:
    64  		return SymVerABI0
    65  	case obj.ABIInternal:
    66  		return SymVerABIInternal
    67  	}
    68  	return -1
    69  }
    70  
    71  func VersionToABI(v int) (obj.ABI, bool) {
    72  	switch v {
    73  	case SymVerABI0:
    74  		return obj.ABI0, true
    75  	case SymVerABIInternal:
    76  		return obj.ABIInternal, true
    77  	}
    78  	return ^obj.ABI(0), false
    79  }
    80  
    81  func (s *Symbol) String() string {
    82  	if s.Version == 0 {
    83  		return s.Name
    84  	}
    85  	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
    86  }
    87  
    88  func (s *Symbol) IsFileLocal() bool {
    89  	return s.Version >= SymVerStatic
    90  }
    91  
    92  func (s *Symbol) ElfsymForReloc() int32 {
    93  	// If putelfsym created a local version of this symbol, use that in all
    94  	// relocations.
    95  	if s.LocalElfsym != 0 {
    96  		return s.LocalElfsym
    97  	} else {
    98  		return s.Elfsym
    99  	}
   100  }
   101  
   102  func (s *Symbol) Len() int64 {
   103  	return s.Size
   104  }
   105  
   106  func (s *Symbol) Grow(siz int64) {
   107  	if int64(int(siz)) != siz {
   108  		log.Fatalf("symgrow size %d too long", siz)
   109  	}
   110  	if int64(len(s.P)) >= siz {
   111  		return
   112  	}
   113  	if cap(s.P) < int(siz) {
   114  		p := make([]byte, 2*(siz+1))
   115  		s.P = append(p[:0], s.P...)
   116  	}
   117  	s.P = s.P[:siz]
   118  }
   119  
   120  func (s *Symbol) AddBytes(bytes []byte) int64 {
   121  	if s.Type == 0 {
   122  		s.Type = SDATA
   123  	}
   124  	s.Attr |= AttrReachable
   125  	s.P = append(s.P, bytes...)
   126  	s.Size = int64(len(s.P))
   127  
   128  	return s.Size
   129  }
   130  
   131  func (s *Symbol) AddUint8(v uint8) int64 {
   132  	off := s.Size
   133  	if s.Type == 0 {
   134  		s.Type = SDATA
   135  	}
   136  	s.Attr |= AttrReachable
   137  	s.Size++
   138  	s.P = append(s.P, v)
   139  
   140  	return off
   141  }
   142  
   143  func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
   144  	return s.AddUintXX(arch, uint64(v), 2)
   145  }
   146  
   147  func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
   148  	return s.AddUintXX(arch, uint64(v), 4)
   149  }
   150  
   151  func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
   152  	return s.AddUintXX(arch, v, 8)
   153  }
   154  
   155  func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
   156  	return s.AddUintXX(arch, v, arch.PtrSize)
   157  }
   158  
   159  func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
   160  	return s.setUintXX(arch, r, uint64(v), 1)
   161  }
   162  
   163  func (s *Symbol) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
   164  	return s.setUintXX(arch, r, uint64(v), 2)
   165  }
   166  
   167  func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
   168  	return s.setUintXX(arch, r, uint64(v), 4)
   169  }
   170  
   171  func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
   172  	return s.setUintXX(arch, r, v, int64(arch.PtrSize))
   173  }
   174  
   175  func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
   176  	if s.Type == 0 {
   177  		s.Type = SDATA
   178  	}
   179  	s.Attr |= AttrReachable
   180  	i := s.Size
   181  	s.Size += int64(arch.PtrSize)
   182  	s.Grow(s.Size)
   183  	r := s.AddRel()
   184  	r.Sym = t
   185  	r.Off = int32(i)
   186  	r.Siz = uint8(arch.PtrSize)
   187  	r.Type = objabi.R_ADDR
   188  	r.Add = add
   189  	return i + int64(r.Siz)
   190  }
   191  
   192  func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
   193  	if s.Type == 0 {
   194  		s.Type = SDATA
   195  	}
   196  	s.Attr |= AttrReachable
   197  	i := s.Size
   198  	s.Size += 4
   199  	s.Grow(s.Size)
   200  	r := s.AddRel()
   201  	r.Sym = t
   202  	r.Off = int32(i)
   203  	r.Add = add
   204  	r.Type = objabi.R_PCREL
   205  	r.Siz = 4
   206  	if arch.Family == sys.S390X {
   207  		r.Variant = RV_390_DBL
   208  	}
   209  	return i + int64(r.Siz)
   210  }
   211  
   212  func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
   213  	return s.AddAddrPlus(arch, t, 0)
   214  }
   215  
   216  func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
   217  	if s.Type == 0 {
   218  		s.Type = SDATA
   219  	}
   220  	s.Attr |= AttrReachable
   221  	if off+int64(arch.PtrSize) > s.Size {
   222  		s.Size = off + int64(arch.PtrSize)
   223  		s.Grow(s.Size)
   224  	}
   225  
   226  	r := s.AddRel()
   227  	r.Sym = t
   228  	r.Off = int32(off)
   229  	r.Siz = uint8(arch.PtrSize)
   230  	r.Type = objabi.R_ADDR
   231  	r.Add = add
   232  	return off + int64(r.Siz)
   233  }
   234  
   235  func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
   236  	return s.SetAddrPlus(arch, off, t, 0)
   237  }
   238  
   239  func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
   240  	if s.Type == 0 {
   241  		s.Type = SDATA
   242  	}
   243  	s.Attr |= AttrReachable
   244  	i := s.Size
   245  	s.Size += int64(arch.PtrSize)
   246  	s.Grow(s.Size)
   247  	r := s.AddRel()
   248  	r.Sym = t
   249  	r.Off = int32(i)
   250  	r.Siz = uint8(arch.PtrSize)
   251  	r.Type = objabi.R_SIZE
   252  	return i + int64(r.Siz)
   253  }
   254  
   255  func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
   256  	if s.Type == 0 {
   257  		s.Type = SDATA
   258  	}
   259  	s.Attr |= AttrReachable
   260  	i := s.Size
   261  	s.Size += 4
   262  	s.Grow(s.Size)
   263  	r := s.AddRel()
   264  	r.Sym = t
   265  	r.Off = int32(i)
   266  	r.Siz = 4
   267  	r.Type = objabi.R_ADDR
   268  	r.Add = add
   269  	return i + int64(r.Siz)
   270  }
   271  
   272  func (s *Symbol) AddRel() *Reloc {
   273  	s.R = append(s.R, Reloc{})
   274  	return &s.R[len(s.R)-1]
   275  }
   276  
   277  func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
   278  	off := s.Size
   279  	s.setUintXX(arch, off, v, int64(wid))
   280  	return off
   281  }
   282  
   283  func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
   284  	if s.Type == 0 {
   285  		s.Type = SDATA
   286  	}
   287  	s.Attr |= AttrReachable
   288  	if s.Size < off+wid {
   289  		s.Size = off + wid
   290  		s.Grow(s.Size)
   291  	}
   292  
   293  	switch wid {
   294  	case 1:
   295  		s.P[off] = uint8(v)
   296  	case 2:
   297  		arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
   298  	case 4:
   299  		arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
   300  	case 8:
   301  		arch.ByteOrder.PutUint64(s.P[off:], v)
   302  	}
   303  
   304  	return off + wid
   305  }
   306  
   307  func (s *Symbol) makeAuxInfo() {
   308  	if s.auxinfo == nil {
   309  		s.auxinfo = &AuxSymbol{extname: s.Name, plt: -1, got: -1}
   310  	}
   311  }
   312  
   313  func (s *Symbol) Extname() string {
   314  	if s.auxinfo == nil {
   315  		return s.Name
   316  	}
   317  	return s.auxinfo.extname
   318  }
   319  
   320  func (s *Symbol) SetExtname(n string) {
   321  	if s.auxinfo == nil {
   322  		if s.Name == n {
   323  			return
   324  		}
   325  		s.makeAuxInfo()
   326  	}
   327  	s.auxinfo.extname = n
   328  }
   329  
   330  func (s *Symbol) Dynimplib() string {
   331  	if s.auxinfo == nil {
   332  		return ""
   333  	}
   334  	return s.auxinfo.dynimplib
   335  }
   336  
   337  func (s *Symbol) Dynimpvers() string {
   338  	if s.auxinfo == nil {
   339  		return ""
   340  	}
   341  	return s.auxinfo.dynimpvers
   342  }
   343  
   344  func (s *Symbol) SetDynimplib(lib string) {
   345  	if s.auxinfo == nil {
   346  		s.makeAuxInfo()
   347  	}
   348  	s.auxinfo.dynimplib = lib
   349  }
   350  
   351  func (s *Symbol) SetDynimpvers(vers string) {
   352  	if s.auxinfo == nil {
   353  		s.makeAuxInfo()
   354  	}
   355  	s.auxinfo.dynimpvers = vers
   356  }
   357  
   358  func (s *Symbol) ResetDyninfo() {
   359  	if s.auxinfo != nil {
   360  		s.auxinfo.dynimplib = ""
   361  		s.auxinfo.dynimpvers = ""
   362  	}
   363  }
   364  
   365  func (s *Symbol) Localentry() uint8 {
   366  	if s.auxinfo == nil {
   367  		return 0
   368  	}
   369  	return s.auxinfo.localentry
   370  }
   371  
   372  func (s *Symbol) SetLocalentry(val uint8) {
   373  	if s.auxinfo == nil {
   374  		if val != 0 {
   375  			return
   376  		}
   377  		s.makeAuxInfo()
   378  	}
   379  	s.auxinfo.localentry = val
   380  }
   381  
   382  func (s *Symbol) Plt() int32 {
   383  	if s.auxinfo == nil {
   384  		return -1
   385  	}
   386  	return s.auxinfo.plt
   387  }
   388  
   389  func (s *Symbol) SetPlt(val int32) {
   390  	if s.auxinfo == nil {
   391  		if val == -1 {
   392  			return
   393  		}
   394  		s.makeAuxInfo()
   395  	}
   396  	s.auxinfo.plt = val
   397  }
   398  
   399  func (s *Symbol) Got() int32 {
   400  	if s.auxinfo == nil {
   401  		return -1
   402  	}
   403  	return s.auxinfo.got
   404  }
   405  
   406  func (s *Symbol) SetGot(val int32) {
   407  	if s.auxinfo == nil {
   408  		if val == -1 {
   409  			return
   410  		}
   411  		s.makeAuxInfo()
   412  	}
   413  	s.auxinfo.got = val
   414  }
   415  
   416  func (s *Symbol) ElfType() elf.SymType {
   417  	if s.auxinfo == nil {
   418  		return elf.STT_NOTYPE
   419  	}
   420  	return s.auxinfo.elftype
   421  }
   422  
   423  func (s *Symbol) SetElfType(val elf.SymType) {
   424  	if s.auxinfo == nil {
   425  		if val == elf.STT_NOTYPE {
   426  			return
   427  		}
   428  		s.makeAuxInfo()
   429  	}
   430  	s.auxinfo.elftype = val
   431  }
   432  
   433  // SortSub sorts a linked-list (by Sub) of *Symbol by Value.
   434  // Used for sub-symbols when loading host objects (see e.g. ldelf.go).
   435  func SortSub(l *Symbol) *Symbol {
   436  	if l == nil || l.Sub == nil {
   437  		return l
   438  	}
   439  
   440  	l1 := l
   441  	l2 := l
   442  	for {
   443  		l2 = l2.Sub
   444  		if l2 == nil {
   445  			break
   446  		}
   447  		l2 = l2.Sub
   448  		if l2 == nil {
   449  			break
   450  		}
   451  		l1 = l1.Sub
   452  	}
   453  
   454  	l2 = l1.Sub
   455  	l1.Sub = nil
   456  	l1 = SortSub(l)
   457  	l2 = SortSub(l2)
   458  
   459  	/* set up lead element */
   460  	if l1.Value < l2.Value {
   461  		l = l1
   462  		l1 = l1.Sub
   463  	} else {
   464  		l = l2
   465  		l2 = l2.Sub
   466  	}
   467  
   468  	le := l
   469  
   470  	for {
   471  		if l1 == nil {
   472  			for l2 != nil {
   473  				le.Sub = l2
   474  				le = l2
   475  				l2 = l2.Sub
   476  			}
   477  
   478  			le.Sub = nil
   479  			break
   480  		}
   481  
   482  		if l2 == nil {
   483  			for l1 != nil {
   484  				le.Sub = l1
   485  				le = l1
   486  				l1 = l1.Sub
   487  			}
   488  
   489  			break
   490  		}
   491  
   492  		if l1.Value < l2.Value {
   493  			le.Sub = l1
   494  			le = l1
   495  			l1 = l1.Sub
   496  		} else {
   497  			le.Sub = l2
   498  			le = l2
   499  			l2 = l2.Sub
   500  		}
   501  	}
   502  
   503  	le.Sub = nil
   504  	return l
   505  }
   506  
   507  type FuncInfo struct {
   508  	Args        int32
   509  	Locals      int32
   510  	Autom       []Auto
   511  	Pcsp        Pcdata
   512  	Pcfile      Pcdata
   513  	Pcline      Pcdata
   514  	Pcinline    Pcdata
   515  	Pcdata      []Pcdata
   516  	Funcdata    []*Symbol
   517  	Funcdataoff []int64
   518  	File        []*Symbol
   519  	InlTree     []InlinedCall
   520  }
   521  
   522  // InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
   523  type InlinedCall struct {
   524  	Parent   int32   // index of parent in InlTree
   525  	File     *Symbol // file of the inlined call
   526  	Line     int32   // line number of the inlined call
   527  	Func     *Symbol // function that was inlined
   528  	ParentPC int32   // PC of the instruction just before the inlined body (offset from function start)
   529  }
   530  
   531  type Pcdata struct {
   532  	P []byte
   533  }
   534  
   535  type Auto struct {
   536  	Asym    *Symbol
   537  	Gotype  *Symbol
   538  	Aoffset int32
   539  	Name    int16
   540  }