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