github.com/euank/go@v0.0.0-20160829210321-495514729181/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/obj"
    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        int16
    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  // Attribute is a set of common symbol attributes.
    93  type Attribute int16
    94  
    95  const (
    96  	AttrDuplicateOK Attribute = 1 << iota
    97  	AttrExternal
    98  	AttrNoSplit
    99  	AttrReachable
   100  	AttrCgoExportDynamic
   101  	AttrCgoExportStatic
   102  	AttrSpecial
   103  	AttrStackCheck
   104  	AttrHidden
   105  	AttrOnList
   106  	AttrLocal
   107  	AttrReflectMethod
   108  )
   109  
   110  func (a Attribute) DuplicateOK() bool      { return a&AttrDuplicateOK != 0 }
   111  func (a Attribute) External() bool         { return a&AttrExternal != 0 }
   112  func (a Attribute) NoSplit() bool          { return a&AttrNoSplit != 0 }
   113  func (a Attribute) Reachable() bool        { return a&AttrReachable != 0 }
   114  func (a Attribute) CgoExportDynamic() bool { return a&AttrCgoExportDynamic != 0 }
   115  func (a Attribute) CgoExportStatic() bool  { return a&AttrCgoExportStatic != 0 }
   116  func (a Attribute) Special() bool          { return a&AttrSpecial != 0 }
   117  func (a Attribute) StackCheck() bool       { return a&AttrStackCheck != 0 }
   118  func (a Attribute) Hidden() bool           { return a&AttrHidden != 0 }
   119  func (a Attribute) OnList() bool           { return a&AttrOnList != 0 }
   120  func (a Attribute) Local() bool            { return a&AttrLocal != 0 }
   121  func (a Attribute) ReflectMethod() bool    { return a&AttrReflectMethod != 0 }
   122  
   123  func (a Attribute) CgoExport() bool {
   124  	return a.CgoExportDynamic() || a.CgoExportStatic()
   125  }
   126  
   127  func (a *Attribute) Set(flag Attribute, value bool) {
   128  	if value {
   129  		*a |= flag
   130  	} else {
   131  		*a &^= flag
   132  	}
   133  }
   134  
   135  type Reloc struct {
   136  	Off     int32
   137  	Siz     uint8
   138  	Done    uint8
   139  	Type    obj.RelocType
   140  	Variant int32
   141  	Add     int64
   142  	Xadd    int64
   143  	Sym     *Symbol
   144  	Xsym    *Symbol
   145  }
   146  
   147  type Auto struct {
   148  	Asym    *Symbol
   149  	Gotype  *Symbol
   150  	Aoffset int32
   151  	Name    int16
   152  }
   153  
   154  type Shlib struct {
   155  	Path            string
   156  	Hash            []byte
   157  	Deps            []string
   158  	File            *elf.File
   159  	gcdataAddresses map[*Symbol]uint64
   160  }
   161  
   162  type Link struct {
   163  	Goarm     int32
   164  	Headtype  int
   165  	Arch      *sys.Arch
   166  	Debugvlog int
   167  	Bso       *bufio.Writer
   168  	Windows   int32
   169  	Goroot    string
   170  
   171  	// Symbol lookup based on name and indexed by version.
   172  	Hash []map[string]*Symbol
   173  
   174  	Allsym    []*Symbol
   175  	Tlsg      *Symbol
   176  	Libdir    []string
   177  	Library   []*Library
   178  	Shlibs    []Shlib
   179  	Tlsoffset int
   180  
   181  	Cursym      *Symbol
   182  	Version     int
   183  	Textp       []*Symbol
   184  	Filesyms    []*Symbol
   185  	Moduledata  *Symbol
   186  	SymbolBatch []Symbol
   187  }
   188  
   189  // The smallest possible offset from the hardware stack pointer to a local
   190  // variable on the stack. Architectures that use a link register save its value
   191  // on the stack in the function prologue and so always have a pointer between
   192  // the hardware stack pointer and the local variable area.
   193  func (ctxt *Link) FixedFrameSize() int64 {
   194  	switch ctxt.Arch.Family {
   195  	case sys.AMD64, sys.I386:
   196  		return 0
   197  	case sys.PPC64:
   198  		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
   199  		// just use that much stack always on ppc64x.
   200  		return int64(4 * ctxt.Arch.PtrSize)
   201  	default:
   202  		return int64(ctxt.Arch.PtrSize)
   203  	}
   204  }
   205  
   206  func (l *Link) IncVersion() {
   207  	l.Version++
   208  	l.Hash = append(l.Hash, make(map[string]*Symbol))
   209  }
   210  
   211  func (l *Link) Logf(format string, args ...interface{}) {
   212  	fmt.Fprintf(l.Bso, format, args...)
   213  	l.Bso.Flush()
   214  }
   215  
   216  type Library struct {
   217  	Objref string
   218  	Srcref string
   219  	File   string
   220  	Pkg    string
   221  	Shlib  string
   222  	hash   []byte
   223  }
   224  
   225  type FuncInfo struct {
   226  	Args        int32
   227  	Locals      int32
   228  	Autom       []Auto
   229  	Pcsp        Pcdata
   230  	Pcfile      Pcdata
   231  	Pcline      Pcdata
   232  	Pcdata      []Pcdata
   233  	Funcdata    []*Symbol
   234  	Funcdataoff []int64
   235  	File        []*Symbol
   236  }
   237  
   238  type Pcdata struct {
   239  	P []byte
   240  }
   241  
   242  type Pciter struct {
   243  	d       Pcdata
   244  	p       []byte
   245  	pc      uint32
   246  	nextpc  uint32
   247  	pcscale uint32
   248  	value   int32
   249  	start   int
   250  	done    int
   251  }
   252  
   253  // Reloc.variant
   254  const (
   255  	RV_NONE = iota
   256  	RV_POWER_LO
   257  	RV_POWER_HI
   258  	RV_POWER_HA
   259  	RV_POWER_DS
   260  
   261  	// RV_390_DBL is a s390x-specific relocation variant that indicates that
   262  	// the value to be placed into the relocatable field should first be
   263  	// divided by 2.
   264  	RV_390_DBL
   265  
   266  	RV_CHECK_OVERFLOW = 1 << 8
   267  	RV_TYPE_MASK      = RV_CHECK_OVERFLOW - 1
   268  )
   269  
   270  // Pcdata iterator.
   271  //	for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
   272  
   273  // Link holds the context for writing object code from a compiler
   274  // to be linker input or for reading that input into the linker.
   275  
   276  // LinkArch is the definition of a single architecture.
   277  
   278  const (
   279  	LinkAuto = 0 + iota
   280  	LinkInternal
   281  	LinkExternal
   282  )