github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/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  	Dupok      uint8
    46  	Cfunc      uint8
    47  	External   uint8
    48  	Nosplit    uint8
    49  	Reachable  bool
    50  	Cgoexport  uint8
    51  	Special    uint8
    52  	Stkcheck   uint8
    53  	Hide       uint8
    54  	Leaf       uint8
    55  	Localentry uint8
    56  	Onlist     uint8
    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  	Dynid       int32
    62  	Plt         int32
    63  	Got         int32
    64  	Align       int32
    65  	Elfsym      int32
    66  	LocalElfsym int32
    67  	Args        int32
    68  	Locals      int32
    69  	Value       int64
    70  	Size        int64
    71  	Allsym      *LSym
    72  	Next        *LSym
    73  	Sub         *LSym
    74  	Outer       *LSym
    75  	Gotype      *LSym
    76  	Reachparent *LSym
    77  	Queue       *LSym
    78  	File        string
    79  	Dynimplib   string
    80  	Dynimpvers  string
    81  	Sect        *Section
    82  	Autom       *Auto
    83  	Pcln        *Pcln
    84  	P           []byte
    85  	R           []Reloc
    86  	Local       bool
    87  }
    88  
    89  func (s *LSym) String() string {
    90  	if s.Version == 0 {
    91  		return s.Name
    92  	}
    93  	return fmt.Sprintf("%s<%d>", s.Name, s.Version)
    94  }
    95  
    96  func (s *LSym) ElfsymForReloc() int32 {
    97  	// If putelfsym created a local version of this symbol, use that in all
    98  	// relocations.
    99  	if s.LocalElfsym != 0 {
   100  		return s.LocalElfsym
   101  	} else {
   102  		return s.Elfsym
   103  	}
   104  }
   105  
   106  type Reloc struct {
   107  	Off     int32
   108  	Siz     uint8
   109  	Done    uint8
   110  	Type    int32
   111  	Variant int32
   112  	Add     int64
   113  	Xadd    int64
   114  	Sym     *LSym
   115  	Xsym    *LSym
   116  }
   117  
   118  type Auto struct {
   119  	Asym    *LSym
   120  	Link    *Auto
   121  	Aoffset int32
   122  	Name    int16
   123  	Gotype  *LSym
   124  }
   125  
   126  type Shlib struct {
   127  	Path             string
   128  	Hash             []byte
   129  	Deps             []string
   130  	File             *elf.File
   131  	gcdata_addresses map[*LSym]uint64
   132  }
   133  
   134  type Link struct {
   135  	Thechar    int32
   136  	Thestring  string
   137  	Goarm      int32
   138  	Headtype   int
   139  	Arch       *LinkArch
   140  	Debugasm   int32
   141  	Debugvlog  int32
   142  	Bso        *obj.Biobuf
   143  	Windows    int32
   144  	Goroot     string
   145  	Hash       map[symVer]*LSym
   146  	Allsym     *LSym
   147  	Nsymbol    int32
   148  	Tlsg       *LSym
   149  	Libdir     []string
   150  	Library    []*Library
   151  	Shlibs     []Shlib
   152  	Tlsoffset  int
   153  	Diag       func(string, ...interface{})
   154  	Cursym     *LSym
   155  	Version    int
   156  	Textp      *LSym
   157  	Etextp     *LSym
   158  	Nhistfile  int32
   159  	Filesyms   *LSym
   160  	Moduledata *LSym
   161  }
   162  
   163  // The smallest possible offset from the hardware stack pointer to a local
   164  // variable on the stack. Architectures that use a link register save its value
   165  // on the stack in the function prologue and so always have a pointer between
   166  // the hardware stack pointer and the local variable area.
   167  func (ctxt *Link) FixedFrameSize() int64 {
   168  	switch ctxt.Arch.Thechar {
   169  	case '6', '8':
   170  		return 0
   171  	case '9':
   172  		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
   173  		// just use that much stack always on ppc64x.
   174  		return int64(4 * ctxt.Arch.Ptrsize)
   175  	default:
   176  		return int64(ctxt.Arch.Ptrsize)
   177  	}
   178  }
   179  
   180  type LinkArch struct {
   181  	ByteOrder binary.ByteOrder
   182  	Name      string
   183  	Thechar   int
   184  	Minlc     int
   185  	Ptrsize   int
   186  	Regsize   int
   187  }
   188  
   189  type Library struct {
   190  	Objref string
   191  	Srcref string
   192  	File   string
   193  	Pkg    string
   194  	Shlib  string
   195  	hash   []byte
   196  }
   197  
   198  type Pcln struct {
   199  	Pcsp        Pcdata
   200  	Pcfile      Pcdata
   201  	Pcline      Pcdata
   202  	Pcdata      []Pcdata
   203  	Npcdata     int
   204  	Funcdata    []*LSym
   205  	Funcdataoff []int64
   206  	Nfuncdata   int
   207  	File        []*LSym
   208  	Nfile       int
   209  	Mfile       int
   210  	Lastfile    *LSym
   211  	Lastindex   int
   212  }
   213  
   214  type Pcdata struct {
   215  	P []byte
   216  }
   217  
   218  type Pciter struct {
   219  	d       Pcdata
   220  	p       []byte
   221  	pc      uint32
   222  	nextpc  uint32
   223  	pcscale uint32
   224  	value   int32
   225  	start   int
   226  	done    int
   227  }
   228  
   229  // Reloc.variant
   230  const (
   231  	RV_NONE = iota
   232  	RV_POWER_LO
   233  	RV_POWER_HI
   234  	RV_POWER_HA
   235  	RV_POWER_DS
   236  	RV_CHECK_OVERFLOW = 1 << 8
   237  	RV_TYPE_MASK      = RV_CHECK_OVERFLOW - 1
   238  )
   239  
   240  // Pcdata iterator.
   241  //	for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
   242  
   243  // Link holds the context for writing object code from a compiler
   244  // to be linker input or for reading that input into the linker.
   245  
   246  // LinkArch is the definition of a single architecture.
   247  
   248  const (
   249  	LinkAuto = 0 + iota
   250  	LinkInternal
   251  	LinkExternal
   252  )