github.com/epfl-dcsl/gotee@v0.0.0-20200909122901-014b35f5e5e9/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/objabi"
     9  	"cmd/internal/sys"
    10  	"debug/elf"
    11  	"fmt"
    12  	"log"
    13  )
    14  
    15  // Symbol is an entry in the symbol table.
    16  type Symbol struct {
    17  	Name        string
    18  	Extname     string
    19  	Type        SymKind
    20  	Version     int16
    21  	Attr        Attribute
    22  	Localentry  uint8
    23  	Dynid       int32
    24  	Plt         int32
    25  	Got         int32
    26  	Align       int32
    27  	Elfsym      int32
    28  	LocalElfsym int32
    29  	Value       int64
    30  	Size        int64
    31  	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
    32  	// is not set for symbols defined by the packages being linked or by symbols
    33  	// read by ldelf (and so is left as elf.STT_NOTYPE).
    34  	ElfType     elf.SymType
    35  	Sub         *Symbol
    36  	Outer       *Symbol
    37  	Gotype      *Symbol
    38  	Reachparent *Symbol
    39  	File        string
    40  	Dynimplib   string
    41  	Dynimpvers  string
    42  	Sect        *Section
    43  	FuncInfo    *FuncInfo
    44  	Lib         *Library // Package defining this symbol
    45  	// P contains the raw symbol data.
    46  	P []byte
    47  	R []Reloc
    48  }
    49  
    50  func (s *Symbol) String() string {
    51  	if s.Version == 0 {
    52  		return s.Name
    53  	}
    54  	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
    55  }
    56  
    57  func (s *Symbol) ElfsymForReloc() int32 {
    58  	// If putelfsym created a local version of this symbol, use that in all
    59  	// relocations.
    60  	if s.LocalElfsym != 0 {
    61  		return s.LocalElfsym
    62  	} else {
    63  		return s.Elfsym
    64  	}
    65  }
    66  
    67  func (s *Symbol) Len() int64 {
    68  	return s.Size
    69  }
    70  
    71  func (s *Symbol) Grow(siz int64) {
    72  	if int64(int(siz)) != siz {
    73  		log.Fatalf("symgrow size %d too long", siz)
    74  	}
    75  	if int64(len(s.P)) >= siz {
    76  		return
    77  	}
    78  	if cap(s.P) < int(siz) {
    79  		p := make([]byte, 2*(siz+1))
    80  		s.P = append(p[:0], s.P...)
    81  	}
    82  	s.P = s.P[:siz]
    83  }
    84  
    85  func (s *Symbol) AddBytes(bytes []byte) int64 {
    86  	if s.Type == 0 {
    87  		s.Type = SDATA
    88  	}
    89  	s.Attr |= AttrReachable
    90  	s.P = append(s.P, bytes...)
    91  	s.Size = int64(len(s.P))
    92  
    93  	return s.Size
    94  }
    95  
    96  func (s *Symbol) AddUint8(v uint8) int64 {
    97  	off := s.Size
    98  	if s.Type == 0 {
    99  		s.Type = SDATA
   100  	}
   101  	s.Attr |= AttrReachable
   102  	s.Size++
   103  	s.P = append(s.P, v)
   104  
   105  	return off
   106  }
   107  
   108  func (s *Symbol) AddUint16(arch *sys.Arch, v uint16) int64 {
   109  	return s.AddUintXX(arch, uint64(v), 2)
   110  }
   111  
   112  func (s *Symbol) AddUint32(arch *sys.Arch, v uint32) int64 {
   113  	return s.AddUintXX(arch, uint64(v), 4)
   114  }
   115  
   116  func (s *Symbol) AddUint64(arch *sys.Arch, v uint64) int64 {
   117  	return s.AddUintXX(arch, v, 8)
   118  }
   119  
   120  func (s *Symbol) AddUint(arch *sys.Arch, v uint64) int64 {
   121  	return s.AddUintXX(arch, v, arch.PtrSize)
   122  }
   123  
   124  func (s *Symbol) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
   125  	return s.setUintXX(arch, r, uint64(v), 1)
   126  }
   127  
   128  func (s *Symbol) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
   129  	return s.setUintXX(arch, r, uint64(v), 4)
   130  }
   131  
   132  func (s *Symbol) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
   133  	return s.setUintXX(arch, r, v, int64(arch.PtrSize))
   134  }
   135  
   136  func (s *Symbol) addAddrPlus(arch *sys.Arch, t *Symbol, add int64, typ objabi.RelocType) int64 {
   137  	if s.Type == 0 {
   138  		s.Type = SDATA
   139  	}
   140  	s.Attr |= AttrReachable
   141  	i := s.Size
   142  	s.Size += int64(arch.PtrSize)
   143  	s.Grow(s.Size)
   144  	r := s.AddRel()
   145  	r.Sym = t
   146  	r.Off = int32(i)
   147  	r.Siz = uint8(arch.PtrSize)
   148  	r.Type = typ
   149  	r.Add = add
   150  	return i + int64(r.Siz)
   151  }
   152  
   153  func (s *Symbol) AddAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
   154  	return s.addAddrPlus(arch, t, add, objabi.R_ADDR)
   155  }
   156  
   157  func (s *Symbol) AddCURelativeAddrPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
   158  	return s.addAddrPlus(arch, t, add, objabi.R_ADDRCUOFF)
   159  }
   160  
   161  func (s *Symbol) AddPCRelPlus(arch *sys.Arch, t *Symbol, add int64) int64 {
   162  	if s.Type == 0 {
   163  		s.Type = SDATA
   164  	}
   165  	s.Attr |= AttrReachable
   166  	i := s.Size
   167  	s.Size += 4
   168  	s.Grow(s.Size)
   169  	r := s.AddRel()
   170  	r.Sym = t
   171  	r.Off = int32(i)
   172  	r.Add = add
   173  	r.Type = objabi.R_PCREL
   174  	r.Siz = 4
   175  	if arch.Family == sys.S390X {
   176  		r.Variant = RV_390_DBL
   177  	}
   178  	return i + int64(r.Siz)
   179  }
   180  
   181  func (s *Symbol) AddAddr(arch *sys.Arch, t *Symbol) int64 {
   182  	return s.AddAddrPlus(arch, t, 0)
   183  }
   184  
   185  func (s *Symbol) SetAddrPlus(arch *sys.Arch, off int64, t *Symbol, add int64) int64 {
   186  	if s.Type == 0 {
   187  		s.Type = SDATA
   188  	}
   189  	s.Attr |= AttrReachable
   190  	if off+int64(arch.PtrSize) > s.Size {
   191  		s.Size = off + int64(arch.PtrSize)
   192  		s.Grow(s.Size)
   193  	}
   194  
   195  	r := s.AddRel()
   196  	r.Sym = t
   197  	r.Off = int32(off)
   198  	r.Siz = uint8(arch.PtrSize)
   199  	r.Type = objabi.R_ADDR
   200  	r.Add = add
   201  	return off + int64(r.Siz)
   202  }
   203  
   204  func (s *Symbol) SetAddr(arch *sys.Arch, off int64, t *Symbol) int64 {
   205  	return s.SetAddrPlus(arch, off, t, 0)
   206  }
   207  
   208  func (s *Symbol) AddSize(arch *sys.Arch, t *Symbol) int64 {
   209  	if s.Type == 0 {
   210  		s.Type = SDATA
   211  	}
   212  	s.Attr |= AttrReachable
   213  	i := s.Size
   214  	s.Size += int64(arch.PtrSize)
   215  	s.Grow(s.Size)
   216  	r := s.AddRel()
   217  	r.Sym = t
   218  	r.Off = int32(i)
   219  	r.Siz = uint8(arch.PtrSize)
   220  	r.Type = objabi.R_SIZE
   221  	return i + int64(r.Siz)
   222  }
   223  
   224  func (s *Symbol) AddAddrPlus4(t *Symbol, add int64) int64 {
   225  	if s.Type == 0 {
   226  		s.Type = SDATA
   227  	}
   228  	s.Attr |= AttrReachable
   229  	i := s.Size
   230  	s.Size += 4
   231  	s.Grow(s.Size)
   232  	r := s.AddRel()
   233  	r.Sym = t
   234  	r.Off = int32(i)
   235  	r.Siz = 4
   236  	r.Type = objabi.R_ADDR
   237  	r.Add = add
   238  	return i + int64(r.Siz)
   239  }
   240  
   241  func (s *Symbol) AddRel() *Reloc {
   242  	s.R = append(s.R, Reloc{})
   243  	return &s.R[len(s.R)-1]
   244  }
   245  
   246  func (s *Symbol) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
   247  	off := s.Size
   248  	s.setUintXX(arch, off, v, int64(wid))
   249  	return off
   250  }
   251  
   252  func (s *Symbol) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
   253  	if s.Type == 0 {
   254  		s.Type = SDATA
   255  	}
   256  	s.Attr |= AttrReachable
   257  	if s.Size < off+wid {
   258  		s.Size = off + wid
   259  		s.Grow(s.Size)
   260  	}
   261  
   262  	switch wid {
   263  	case 1:
   264  		s.P[off] = uint8(v)
   265  	case 2:
   266  		arch.ByteOrder.PutUint16(s.P[off:], uint16(v))
   267  	case 4:
   268  		arch.ByteOrder.PutUint32(s.P[off:], uint32(v))
   269  	case 8:
   270  		arch.ByteOrder.PutUint64(s.P[off:], v)
   271  	}
   272  
   273  	return off + wid
   274  }
   275  
   276  // SortSub sorts a linked-list (by Sub) of *Symbol by Value.
   277  // Used for sub-symbols when loading host objects (see e.g. ldelf.go).
   278  func SortSub(l *Symbol) *Symbol {
   279  	if l == nil || l.Sub == nil {
   280  		return l
   281  	}
   282  
   283  	l1 := l
   284  	l2 := l
   285  	for {
   286  		l2 = l2.Sub
   287  		if l2 == nil {
   288  			break
   289  		}
   290  		l2 = l2.Sub
   291  		if l2 == nil {
   292  			break
   293  		}
   294  		l1 = l1.Sub
   295  	}
   296  
   297  	l2 = l1.Sub
   298  	l1.Sub = nil
   299  	l1 = SortSub(l)
   300  	l2 = SortSub(l2)
   301  
   302  	/* set up lead element */
   303  	if l1.Value < l2.Value {
   304  		l = l1
   305  		l1 = l1.Sub
   306  	} else {
   307  		l = l2
   308  		l2 = l2.Sub
   309  	}
   310  
   311  	le := l
   312  
   313  	for {
   314  		if l1 == nil {
   315  			for l2 != nil {
   316  				le.Sub = l2
   317  				le = l2
   318  				l2 = l2.Sub
   319  			}
   320  
   321  			le.Sub = nil
   322  			break
   323  		}
   324  
   325  		if l2 == nil {
   326  			for l1 != nil {
   327  				le.Sub = l1
   328  				le = l1
   329  				l1 = l1.Sub
   330  			}
   331  
   332  			break
   333  		}
   334  
   335  		if l1.Value < l2.Value {
   336  			le.Sub = l1
   337  			le = l1
   338  			l1 = l1.Sub
   339  		} else {
   340  			le.Sub = l2
   341  			le = l2
   342  			l2 = l2.Sub
   343  		}
   344  	}
   345  
   346  	le.Sub = nil
   347  	return l
   348  }
   349  
   350  type FuncInfo struct {
   351  	Args        int32
   352  	Locals      int32
   353  	Autom       []Auto
   354  	Pcsp        Pcdata
   355  	Pcfile      Pcdata
   356  	Pcline      Pcdata
   357  	Pcinline    Pcdata
   358  	Pcdata      []Pcdata
   359  	Funcdata    []*Symbol
   360  	Funcdataoff []int64
   361  	File        []*Symbol
   362  	InlTree     []InlinedCall
   363  }
   364  
   365  // InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
   366  type InlinedCall struct {
   367  	Parent int32   // index of parent in InlTree
   368  	File   *Symbol // file of the inlined call
   369  	Line   int32   // line number of the inlined call
   370  	Func   *Symbol // function that was inlined
   371  }
   372  
   373  type Pcdata struct {
   374  	P []byte
   375  }
   376  
   377  type Auto struct {
   378  	Asym    *Symbol
   379  	Gotype  *Symbol
   380  	Aoffset int32
   381  	Name    int16
   382  }