github.com/sanprasirt/go@v0.0.0-20170607001320-a027466e4b6d/src/cmd/link/internal/ld/link.go (about)

     1  // Derived from Inferno utils/6l/l.h and related files.
     2  // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/6l/l.h
     3  //
     4  //	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
     5  //	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
     6  //	Portions Copyright © 1997-1999 Vita Nuova Limited
     7  //	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
     8  //	Portions Copyright © 2004,2006 Bruce Ellis
     9  //	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
    10  //	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
    11  //	Portions Copyright © 2009 The Go Authors. All rights reserved.
    12  //
    13  // Permission is hereby granted, free of charge, to any person obtaining a copy
    14  // of this software and associated documentation files (the "Software"), to deal
    15  // in the Software without restriction, including without limitation the rights
    16  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    17  // copies of the Software, and to permit persons to whom the Software is
    18  // furnished to do so, subject to the following conditions:
    19  //
    20  // The above copyright notice and this permission notice shall be included in
    21  // all copies or substantial portions of the Software.
    22  //
    23  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    24  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    25  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    26  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    27  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    28  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    29  // THE SOFTWARE.
    30  
    31  package ld
    32  
    33  import (
    34  	"bufio"
    35  	"cmd/internal/objabi"
    36  	"cmd/internal/sys"
    37  	"debug/elf"
    38  	"fmt"
    39  )
    40  
    41  // Symbol is an entry in the symbol table.
    42  type Symbol struct {
    43  	Name        string
    44  	Extname     string
    45  	Type        SymKind
    46  	Version     int16
    47  	Attr        Attribute
    48  	Localentry  uint8
    49  	Dynid       int32
    50  	Plt         int32
    51  	Got         int32
    52  	Align       int32
    53  	Elfsym      int32
    54  	LocalElfsym int32
    55  	Value       int64
    56  	Size        int64
    57  	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
    58  	// is not set for symbols defined by the packages being linked or by symbols
    59  	// read by ldelf (and so is left as elf.STT_NOTYPE).
    60  	ElfType     elf.SymType
    61  	Sub         *Symbol
    62  	Outer       *Symbol
    63  	Gotype      *Symbol
    64  	Reachparent *Symbol
    65  	File        string
    66  	Dynimplib   string
    67  	Dynimpvers  string
    68  	Sect        *Section
    69  	FuncInfo    *FuncInfo
    70  	// P contains the raw symbol data.
    71  	P []byte
    72  	R []Reloc
    73  }
    74  
    75  func (s *Symbol) String() string {
    76  	if s.Version == 0 {
    77  		return s.Name
    78  	}
    79  	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
    80  }
    81  
    82  func (s *Symbol) ElfsymForReloc() int32 {
    83  	// If putelfsym created a local version of this symbol, use that in all
    84  	// relocations.
    85  	if s.LocalElfsym != 0 {
    86  		return s.LocalElfsym
    87  	} else {
    88  		return s.Elfsym
    89  	}
    90  }
    91  
    92  func (s *Symbol) Len() int64 {
    93  	return s.Size
    94  }
    95  
    96  // Attribute is a set of common symbol attributes.
    97  type Attribute int16
    98  
    99  const (
   100  	// AttrDuplicateOK marks a symbol that can be present in multiple object
   101  	// files.
   102  	AttrDuplicateOK Attribute = 1 << iota
   103  	// AttrExternal marks function symbols loaded from host object files.
   104  	AttrExternal
   105  	// AttrNoSplit marks functions that cannot split the stack; the linker
   106  	// cares because it checks that there are no call chains of nosplit
   107  	// functions that require more than StackLimit bytes (see
   108  	// lib.go:dostkcheck)
   109  	AttrNoSplit
   110  	// AttrReachable marks symbols that are transitively referenced from the
   111  	// entry points. Unreachable symbols are not written to the output.
   112  	AttrReachable
   113  	// AttrCgoExportDynamic and AttrCgoExportStatic mark symbols referenced
   114  	// by directives written by cgo (in response to //export directives in
   115  	// the source).
   116  	AttrCgoExportDynamic
   117  	AttrCgoExportStatic
   118  	// AttrSpecial marks symbols that do not have their address (i.e. Value)
   119  	// computed by the usual mechanism of data.go:dodata() &
   120  	// data.go:address().
   121  	AttrSpecial
   122  	// AttrStackCheck is used by dostkcheck to only check each NoSplit
   123  	// function's stack usage once.
   124  	AttrStackCheck
   125  	// AttrNotInSymbolTable marks symbols that are not written to the symbol table.
   126  	AttrNotInSymbolTable
   127  	// AttrOnList marks symbols that are on some list (such as the list of
   128  	// all text symbols, or one of the lists of data symbols) and is
   129  	// consulted to avoid bugs where a symbol is put on a list twice.
   130  	AttrOnList
   131  	// AttrLocal marks symbols that are only visible within the module
   132  	// (exectuable or shared library) being linked. Only relevant when
   133  	// dynamically linking Go code.
   134  	AttrLocal
   135  	// AttrReflectMethod marks certain methods from the reflect package that
   136  	// can be used to call arbitrary methods. If no symbol with this bit set
   137  	// is marked as reachable, more dead code elimination can be done.
   138  	AttrReflectMethod
   139  	// AttrMakeTypelink Amarks types that should be added to the typelink
   140  	// table. See typelinks.go:typelinks().
   141  	AttrMakeTypelink
   142  	// AttrShared marks symbols compiled with the -shared option.
   143  	AttrShared
   144  	// 14 attributes defined so far.
   145  )
   146  
   147  func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
   148  func (a Attribute) External() bool         { return a&AttrExternal != 0 }
   149  func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
   150  func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
   151  func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
   152  func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
   153  func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
   154  func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
   155  func (a Attribute) NotInSymbolTable() bool { return a&AttrNotInSymbolTable != 0 }
   156  func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
   157  func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
   158  func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
   159  func (a Attribute) MakeTypelink() bool     { return a&AttrMakeTypelink != 0 }
   160  func (a Attribute) Shared() bool           { return a&AttrShared != 0 }
   161  
   162  func (a Attribute) CgoExport() bool {
   163  	return a.CgoExportDynamic() || a.CgoExportStatic()
   164  }
   165  
   166  func (a *Attribute) Set(flag Attribute, value bool) {
   167  	if value {
   168  		*a |= flag
   169  	} else {
   170  		*a &^= flag
   171  	}
   172  }
   173  
   174  // Reloc is a relocation.
   175  //
   176  // The typical Reloc rewrites part of a symbol at offset Off to address Sym.
   177  // A Reloc is stored in a slice on the Symbol it rewrites.
   178  //
   179  // Relocations are generated by the compiler as the type
   180  // cmd/internal/obj.Reloc, which is encoded into the object file wire
   181  // format and decoded by the linker into this type. A separate type is
   182  // used to hold linker-specific state about the relocation.
   183  //
   184  // Some relocations are created by cmd/link.
   185  type Reloc struct {
   186  	Off     int32            // offset to rewrite
   187  	Siz     uint8            // number of bytes to rewrite, 1, 2, or 4
   188  	Done    uint8            // set to 1 when relocation is complete
   189  	Variant RelocVariant     // variation on Type
   190  	Type    objabi.RelocType // the relocation type
   191  	Add     int64            // addend
   192  	Xadd    int64            // addend passed to external linker
   193  	Sym     *Symbol          // symbol the relocation addresses
   194  	Xsym    *Symbol          // symbol passed to external linker
   195  }
   196  
   197  type Auto struct {
   198  	Asym    *Symbol
   199  	Gotype  *Symbol
   200  	Aoffset int32
   201  	Name    int16
   202  }
   203  
   204  type Shlib struct {
   205  	Path            string
   206  	Hash            []byte
   207  	Deps            []string
   208  	File            *elf.File
   209  	gcdataAddresses map[*Symbol]uint64
   210  }
   211  
   212  // Link holds the context for writing object code from a compiler
   213  // or for reading that input into the linker.
   214  type Link struct {
   215  	Syms *Symbols
   216  
   217  	Arch      *sys.Arch
   218  	Debugvlog int
   219  	Bso       *bufio.Writer
   220  
   221  	Loaded bool // set after all inputs have been loaded as symbols
   222  
   223  	Tlsg         *Symbol
   224  	Libdir       []string
   225  	Library      []*Library
   226  	LibraryByPkg map[string]*Library
   227  	Shlibs       []Shlib
   228  	Tlsoffset    int
   229  	Textp        []*Symbol
   230  	Filesyms     []*Symbol
   231  	Moduledata   *Symbol
   232  
   233  	PackageFile  map[string]string
   234  	PackageShlib map[string]string
   235  
   236  	tramps []*Symbol // trampolines
   237  }
   238  
   239  // The smallest possible offset from the hardware stack pointer to a local
   240  // variable on the stack. Architectures that use a link register save its value
   241  // on the stack in the function prologue and so always have a pointer between
   242  // the hardware stack pointer and the local variable area.
   243  func (ctxt *Link) FixedFrameSize() int64 {
   244  	switch ctxt.Arch.Family {
   245  	case sys.AMD64, sys.I386:
   246  		return 0
   247  	case sys.PPC64:
   248  		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
   249  		// just use that much stack always on ppc64x.
   250  		return int64(4 * ctxt.Arch.PtrSize)
   251  	default:
   252  		return int64(ctxt.Arch.PtrSize)
   253  	}
   254  }
   255  
   256  func (l *Link) Logf(format string, args ...interface{}) {
   257  	fmt.Fprintf(l.Bso, format, args...)
   258  	l.Bso.Flush()
   259  }
   260  
   261  type Library struct {
   262  	Objref      string
   263  	Srcref      string
   264  	File        string
   265  	Pkg         string
   266  	Shlib       string
   267  	hash        string
   268  	imports     []*Library
   269  	textp       []*Symbol // text symbols defined in this library
   270  	dupTextSyms []*Symbol // dupok text symbols defined in this library
   271  }
   272  
   273  func (l Library) String() string {
   274  	return l.Pkg
   275  }
   276  
   277  type FuncInfo struct {
   278  	Args        int32
   279  	Locals      int32
   280  	Autom       []Auto
   281  	Pcsp        Pcdata
   282  	Pcfile      Pcdata
   283  	Pcline      Pcdata
   284  	Pcinline    Pcdata
   285  	Pcdata      []Pcdata
   286  	Funcdata    []*Symbol
   287  	Funcdataoff []int64
   288  	File        []*Symbol
   289  	InlTree     []InlinedCall
   290  }
   291  
   292  // InlinedCall is a node in a local inlining tree (FuncInfo.InlTree).
   293  type InlinedCall struct {
   294  	Parent int32   // index of parent in InlTree
   295  	File   *Symbol // file of the inlined call
   296  	Line   int32   // line number of the inlined call
   297  	Func   *Symbol // function that was inlined
   298  }
   299  
   300  type Pcdata struct {
   301  	P []byte
   302  }
   303  
   304  type Pciter struct {
   305  	d       Pcdata
   306  	p       []byte
   307  	pc      uint32
   308  	nextpc  uint32
   309  	pcscale uint32
   310  	value   int32
   311  	start   int
   312  	done    int
   313  }
   314  
   315  // RelocVariant is a linker-internal variation on a relocation.
   316  type RelocVariant uint8
   317  
   318  const (
   319  	RV_NONE RelocVariant = iota
   320  	RV_POWER_LO
   321  	RV_POWER_HI
   322  	RV_POWER_HA
   323  	RV_POWER_DS
   324  
   325  	// RV_390_DBL is a s390x-specific relocation variant that indicates that
   326  	// the value to be placed into the relocatable field should first be
   327  	// divided by 2.
   328  	RV_390_DBL
   329  
   330  	RV_CHECK_OVERFLOW RelocVariant = 1 << 7
   331  	RV_TYPE_MASK      RelocVariant = RV_CHECK_OVERFLOW - 1
   332  )