github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/cmd/link/internal/ld/link.go (about)

     1  // Derived from Inferno utils/6l/l.h and related files.
     2  // http://code.google.com/p/inferno-os/source/browse/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/sys"
    36  	"debug/elf"
    37  	"fmt"
    38  )
    39  
    40  type LSym struct {
    41  	Name        string
    42  	Extname     string
    43  	Type        int16
    44  	Version     int16
    45  	Attr        Attribute
    46  	Localentry  uint8
    47  	Dynid       int32
    48  	Plt         int32
    49  	Got         int32
    50  	Align       int32
    51  	Elfsym      int32
    52  	LocalElfsym int32
    53  	Value       int64
    54  	Size        int64
    55  	// ElfType is set for symbols read from shared libraries by ldshlibsyms. It
    56  	// is not set for symbols defined by the packages being linked or by symbols
    57  	// read by ldelf (and so is left as elf.STT_NOTYPE).
    58  	ElfType     elf.SymType
    59  	Next        *LSym
    60  	Sub         *LSym
    61  	Outer       *LSym
    62  	Gotype      *LSym
    63  	Reachparent *LSym
    64  	File        string
    65  	Dynimplib   string
    66  	Dynimpvers  string
    67  	Sect        *Section
    68  	FuncInfo    *FuncInfo
    69  	P           []byte
    70  	R           []Reloc
    71  }
    72  
    73  func (s *LSym) String() string {
    74  	if s.Version == 0 {
    75  		return s.Name
    76  	}
    77  	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
    78  }
    79  
    80  func (s *LSym) ElfsymForReloc() int32 {
    81  	// If putelfsym created a local version of this symbol, use that in all
    82  	// relocations.
    83  	if s.LocalElfsym != 0 {
    84  		return s.LocalElfsym
    85  	} else {
    86  		return s.Elfsym
    87  	}
    88  }
    89  
    90  // Attribute is a set of common symbol attributes.
    91  type Attribute int16
    92  
    93  const (
    94  	AttrDuplicateOK Attribute = 1 << iota
    95  	AttrExternal
    96  	AttrNoSplit
    97  	AttrReachable
    98  	AttrCgoExportDynamic
    99  	AttrCgoExportStatic
   100  	AttrSpecial
   101  	AttrStackCheck
   102  	AttrHidden
   103  	AttrOnList
   104  	AttrLocal
   105  	AttrReflectMethod
   106  )
   107  
   108  func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
   109  func (a Attribute) External() bool         { return a&AttrExternal != 0 }
   110  func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
   111  func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
   112  func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
   113  func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
   114  func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
   115  func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
   116  func (a Attribute) Hidden() bool           { return a&AttrHidden != 0 }
   117  func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
   118  func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
   119  func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
   120  
   121  func (a Attribute) CgoExport() bool {
   122  	return a.CgoExportDynamic() || a.CgoExportStatic()
   123  }
   124  
   125  func (a *Attribute) Set(flag Attribute, value bool) {
   126  	if value {
   127  		*a |= flag
   128  	} else {
   129  		*a &^= flag
   130  	}
   131  }
   132  
   133  type Reloc struct {
   134  	Off     int32
   135  	Siz     uint8
   136  	Done    uint8
   137  	Type    int32
   138  	Variant int32
   139  	Add     int64
   140  	Xadd    int64
   141  	Sym     *LSym
   142  	Xsym    *LSym
   143  }
   144  
   145  type Auto struct {
   146  	Asym    *LSym
   147  	Gotype  *LSym
   148  	Aoffset int32
   149  	Name    int16
   150  }
   151  
   152  type Shlib struct {
   153  	Path             string
   154  	Hash             []byte
   155  	Deps             []string
   156  	File             *elf.File
   157  	gcdata_addresses map[*LSym]uint64
   158  }
   159  
   160  type Link struct {
   161  	Goarm     int32
   162  	Headtype  int
   163  	Arch      *sys.Arch
   164  	Debugvlog int32
   165  	Bso       *bufio.Writer
   166  	Windows   int32
   167  	Goroot    string
   168  
   169  	// Symbol lookup based on name and indexed by version.
   170  	Hash []map[string]*LSym
   171  
   172  	Allsym     []*LSym
   173  	Tlsg       *LSym
   174  	Libdir     []string
   175  	Library    []*Library
   176  	Shlibs     []Shlib
   177  	Tlsoffset  int
   178  	Diag       func(string, ...interface{})
   179  	Cursym     *LSym
   180  	Version    int
   181  	Textp      []*LSym
   182  	Filesyms   []*LSym
   183  	Moduledata *LSym
   184  	LSymBatch  []LSym
   185  }
   186  
   187  // The smallest possible offset from the hardware stack pointer to a local
   188  // variable on the stack. Architectures that use a link register save its value
   189  // on the stack in the function prologue and so always have a pointer between
   190  // the hardware stack pointer and the local variable area.
   191  func (ctxt *Link) FixedFrameSize() int64 {
   192  	switch ctxt.Arch.Family {
   193  	case sys.AMD64, sys.I386:
   194  		return 0
   195  	case sys.PPC64:
   196  		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
   197  		// just use that much stack always on ppc64x.
   198  		return int64(4 * ctxt.Arch.PtrSize)
   199  	case sys.SPARC64:
   200  		// SPARC64 always requires 176 bytes of stack.
   201  		return int64(16*8 + 6*8)
   202  	default:
   203  		return int64(ctxt.Arch.PtrSize)
   204  	}
   205  }
   206  
   207  func (l *Link) IncVersion() {
   208  	l.Version++
   209  	l.Hash = append(l.Hash, make(map[string]*LSym))
   210  }
   211  
   212  type Library struct {
   213  	Objref string
   214  	Srcref string
   215  	File   string
   216  	Pkg    string
   217  	Shlib  string
   218  	hash   []byte
   219  }
   220  
   221  type FuncInfo struct {
   222  	Args        int32
   223  	Locals      int32
   224  	Autom       []Auto
   225  	Pcsp        Pcdata
   226  	Pcfile      Pcdata
   227  	Pcline      Pcdata
   228  	Pcdata      []Pcdata
   229  	Funcdata    []*LSym
   230  	Funcdataoff []int64
   231  	File        []*LSym
   232  }
   233  
   234  type Pcdata struct {
   235  	P []byte
   236  }
   237  
   238  type Pciter struct {
   239  	d       Pcdata
   240  	p       []byte
   241  	pc      uint32
   242  	nextpc  uint32
   243  	pcscale uint32
   244  	value   int32
   245  	start   int
   246  	done    int
   247  }
   248  
   249  // Reloc.variant
   250  const (
   251  	RV_NONE = iota
   252  	RV_POWER_LO
   253  	RV_POWER_HI
   254  	RV_POWER_HA
   255  	RV_POWER_DS
   256  
   257  	// RV_390_DBL is a s390x-specific relocation variant that indicates that
   258  	// the value to be placed into the relocatable field should first be
   259  	// divided by 2.
   260  	RV_390_DBL
   261  
   262  	RV_CHECK_OVERFLOW = 1 << 8
   263  	RV_TYPE_MASK      = RV_CHECK_OVERFLOW - 1
   264  )
   265  
   266  // Pcdata iterator.
   267  //	for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
   268  
   269  // Link holds the context for writing object code from a compiler
   270  // to be linker input or for reading that input into the linker.
   271  
   272  // LinkArch is the definition of a single architecture.
   273  
   274  const (
   275  	LinkAuto = 0 + iota
   276  	LinkInternal
   277  	LinkExternal
   278  )