github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/cmd/internal/obj/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 obj
    32  
    33  import "encoding/binary"
    34  
    35  // An Addr is an argument to an instruction.
    36  // The general forms and their encodings are:
    37  //
    38  //	sym±offset(symkind)(reg)(index*scale)
    39  //		Memory reference at address &sym(symkind) + offset + reg + index*scale.
    40  //		Any of sym(symkind), ±offset, (reg), (index*scale), and *scale can be omitted.
    41  //		If (reg) and *scale are both omitted, the resulting expression (index) is parsed as (reg).
    42  //		To force a parsing as index*scale, write (index*1).
    43  //		Encoding:
    44  //			type = TYPE_MEM
    45  //			name = symkind (NAME_AUTO, ...) or 0 (NAME_NONE)
    46  //			sym = sym
    47  //			offset = ±offset
    48  //			reg = reg (REG_*)
    49  //			index = index (REG_*)
    50  //			scale = scale (1, 2, 4, 8)
    51  //
    52  //	$<mem>
    53  //		Effective address of memory reference <mem>, defined above.
    54  //		Encoding: same as memory reference, but type = TYPE_ADDR.
    55  //
    56  //	$<±integer value>
    57  //		This is a special case of $<mem>, in which only ±offset is present.
    58  //		It has a separate type for easy recognition.
    59  //		Encoding:
    60  //			type = TYPE_CONST
    61  //			offset = ±integer value
    62  //
    63  //	*<mem>
    64  //		Indirect reference through memory reference <mem>, defined above.
    65  //		Only used on x86 for CALL/JMP *sym(SB), which calls/jumps to a function
    66  //		pointer stored in the data word sym(SB), not a function named sym(SB).
    67  //		Encoding: same as above, but type = TYPE_INDIR.
    68  //
    69  //	$*$<mem>
    70  //		No longer used.
    71  //		On machines with actual SB registers, $*$<mem> forced the
    72  //		instruction encoding to use a full 32-bit constant, never a
    73  //		reference relative to SB.
    74  //
    75  //	$<floating point literal>
    76  //		Floating point constant value.
    77  //		Encoding:
    78  //			type = TYPE_FCONST
    79  //			val = floating point value
    80  //
    81  //	$<string literal, up to 8 chars>
    82  //		String literal value (raw bytes used for DATA instruction).
    83  //		Encoding:
    84  //			type = TYPE_SCONST
    85  //			val = string
    86  //
    87  //	<register name>
    88  //		Any register: integer, floating point, control, segment, and so on.
    89  //		If looking for specific register kind, must check type and reg value range.
    90  //		Encoding:
    91  //			type = TYPE_REG
    92  //			reg = reg (REG_*)
    93  //
    94  //	x(PC)
    95  //		Encoding:
    96  //			type = TYPE_BRANCH
    97  //			val = Prog* reference OR ELSE offset = target pc (branch takes priority)
    98  //
    99  //	$±x-±y
   100  //		Final argument to TEXT, specifying local frame size x and argument size y.
   101  //		In this form, x and y are integer literals only, not arbitrary expressions.
   102  //		This avoids parsing ambiguities due to the use of - as a separator.
   103  //		The ± are optional.
   104  //		If the final argument to TEXT omits the -±y, the encoding should still
   105  //		use TYPE_TEXTSIZE (not TYPE_CONST), with u.argsize = ArgsSizeUnknown.
   106  //		Encoding:
   107  //			type = TYPE_TEXTSIZE
   108  //			offset = x
   109  //			val = int32(y)
   110  //
   111  //	reg<<shift, reg>>shift, reg->shift, reg@>shift
   112  //		Shifted register value, for ARM.
   113  //		In this form, reg must be a register and shift can be a register or an integer constant.
   114  //		Encoding:
   115  //			type = TYPE_SHIFT
   116  //			offset = (reg&15) | shifttype<<5 | count
   117  //			shifttype = 0, 1, 2, 3 for <<, >>, ->, @>
   118  //			count = (reg&15)<<8 | 1<<4 for a register shift count, (n&31)<<7 for an integer constant.
   119  //
   120  //	(reg, reg)
   121  //		A destination register pair. When used as the last argument of an instruction,
   122  //		this form makes clear that both registers are destinations.
   123  //		Encoding:
   124  //			type = TYPE_REGREG
   125  //			reg = first register
   126  //			offset = second register
   127  //
   128  //	[reg, reg, reg-reg]
   129  //		Register list for ARM.
   130  //		Encoding:
   131  //			type = TYPE_REGLIST
   132  //			offset = bit mask of registers in list; R0 is low bit.
   133  //
   134  //	reg, reg
   135  //		Register pair for ARM.
   136  //		TYPE_REGREG2
   137  //
   138  //	(reg+reg)
   139  //		Register pair for PPC64.
   140  //		Encoding:
   141  //			type = TYPE_MEM
   142  //			reg = first register
   143  //			index = second register
   144  //			scale = 1
   145  //
   146  type Addr struct {
   147  	Type   int16
   148  	Reg    int16
   149  	Reg2   int16 // RHS of register pair. AX:DX (386)
   150  	Index  int16
   151  	Scale  int16 // Sometimes holds a register.
   152  	Name   int8
   153  	Class  int8
   154  	Etype  uint8
   155  	Offset int64
   156  	Width  int64
   157  	Sym    *LSym
   158  	Gotype *LSym
   159  
   160  	// argument value:
   161  	//	for TYPE_SCONST, a string
   162  	//	for TYPE_FCONST, a float64
   163  	//	for TYPE_BRANCH, a *Prog (optional)
   164  	//	for TYPE_TEXTSIZE, an int32 (optional)
   165  	Val interface{}
   166  
   167  	Node interface{} // for use by compiler
   168  }
   169  
   170  const (
   171  	NAME_NONE = 0 + iota
   172  	NAME_EXTERN
   173  	NAME_STATIC
   174  	NAME_AUTO
   175  	NAME_PARAM
   176  	// A reference to name@GOT(SB) is a reference to the entry in the global offset
   177  	// table for 'name'.
   178  	NAME_GOTREF
   179  )
   180  
   181  const (
   182  	TYPE_NONE = 0
   183  )
   184  
   185  const (
   186  	TYPE_BRANCH = 5 + iota
   187  	TYPE_TEXTSIZE
   188  	TYPE_MEM
   189  	TYPE_CONST
   190  	TYPE_FCONST
   191  	TYPE_SCONST
   192  	TYPE_REG
   193  	TYPE_ADDR
   194  	TYPE_SHIFT
   195  	TYPE_REGREG
   196  	TYPE_REGREG2
   197  	TYPE_INDIR
   198  	TYPE_REGLIST
   199  )
   200  
   201  // TODO(rsc): Describe prog.
   202  // TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
   203  type Prog struct {
   204  	Ctxt     *Link
   205  	Link     *Prog
   206  	From     Addr
   207  	From3    Addr
   208  	To       Addr
   209  	To2      Addr
   210  	Opt      interface{}
   211  	Forwd    *Prog
   212  	Pcond    *Prog
   213  	Comefrom *Prog
   214  	Pcrel    *Prog
   215  	Pc       int64
   216  	Lineno   int32
   217  	Spadj    int32
   218  	As       int16
   219  	Reg      int16
   220  	Mark     uint16
   221  	Optab    uint16
   222  	Scond    uint8
   223  	Back     uint8
   224  	Ft       uint8
   225  	F3t      uint8
   226  	Tt       uint8
   227  	Isize    uint8
   228  	Printed  uint8
   229  	Width    int8
   230  	Mode     int8
   231  
   232  	Info ProgInfo
   233  }
   234  
   235  // ProgInfo holds information about the instruction for use
   236  // by clients such as the compiler. The exact meaning of this
   237  // data is up to the client and is not interpreted by the cmd/internal/obj/... packages.
   238  type ProgInfo struct {
   239  	Flags    uint32 // flag bits
   240  	Reguse   uint64 // registers implicitly used by this instruction
   241  	Regset   uint64 // registers implicitly set by this instruction
   242  	Regindex uint64 // registers used by addressing mode
   243  }
   244  
   245  // Prog.as opcodes.
   246  // These are the portable opcodes, common to all architectures.
   247  // Each architecture defines many more arch-specific opcodes,
   248  // with values starting at A_ARCHSPECIFIC.
   249  // Each architecture adds an offset to this so each machine has
   250  // distinct space for its instructions. The offset is a power of
   251  // two so it can be masked to return to origin zero.
   252  // See the definitions of ABase386 etc.
   253  const (
   254  	AXXX = 0 + iota
   255  	ACALL
   256  	ACHECKNIL
   257  	ADATA
   258  	ADUFFCOPY
   259  	ADUFFZERO
   260  	AEND
   261  	AFUNCDATA
   262  	AGLOBL
   263  	AJMP
   264  	ANOP
   265  	APCDATA
   266  	ARET
   267  	ATEXT
   268  	ATYPE
   269  	AUNDEF
   270  	AUSEFIELD
   271  	AVARDEF
   272  	AVARKILL
   273  	A_ARCHSPECIFIC
   274  )
   275  
   276  type LSym struct {
   277  	Name      string
   278  	Type      int16
   279  	Version   int16
   280  	Dupok     uint8
   281  	Cfunc     uint8
   282  	Nosplit   uint8
   283  	Leaf      uint8
   284  	Seenglobl uint8
   285  	Onlist    uint8
   286  	Args      int32
   287  	Locals    int32
   288  	Value     int64
   289  	Size      int64
   290  	Next      *LSym
   291  	Gotype    *LSym
   292  	Autom     *Auto
   293  	Text      *Prog
   294  	Etext     *Prog
   295  	Pcln      *Pcln
   296  	P         []byte
   297  	R         []Reloc
   298  }
   299  
   300  type Pcln struct {
   301  	Pcsp        Pcdata
   302  	Pcfile      Pcdata
   303  	Pcline      Pcdata
   304  	Pcdata      []Pcdata
   305  	Funcdata    []*LSym
   306  	Funcdataoff []int64
   307  	File        []*LSym
   308  	Lastfile    *LSym
   309  	Lastindex   int
   310  }
   311  
   312  // LSym.type
   313  const (
   314  	Sxxx = iota
   315  	STEXT
   316  	SELFRXSECT
   317  	STYPE
   318  	SSTRING
   319  	SGOSTRING
   320  	SGOFUNC
   321  	SRODATA
   322  	SFUNCTAB
   323  	STYPELINK
   324  	SSYMTAB
   325  	SPCLNTAB
   326  	SELFROSECT
   327  	SMACHOPLT
   328  	SELFSECT
   329  	SMACHO
   330  	SMACHOGOT
   331  	SWINDOWS
   332  	SELFGOT
   333  	SNOPTRDATA
   334  	SINITARR
   335  	SDATA
   336  	SBSS
   337  	SNOPTRBSS
   338  	STLSBSS
   339  	SXREF
   340  	SMACHOSYMSTR
   341  	SMACHOSYMTAB
   342  	SMACHOINDIRECTPLT
   343  	SMACHOINDIRECTGOT
   344  	SFILE
   345  	SFILEPATH
   346  	SCONST
   347  	SDYNIMPORT
   348  	SHOSTOBJ
   349  	SSUB    = 1 << 8
   350  	SMASK   = SSUB - 1
   351  	SHIDDEN = 1 << 9
   352  )
   353  
   354  type Reloc struct {
   355  	Off  int32
   356  	Siz  uint8
   357  	Type int32
   358  	Add  int64
   359  	Xadd int64
   360  	Sym  *LSym
   361  	Xsym *LSym
   362  }
   363  
   364  // Reloc.type
   365  const (
   366  	R_ADDR = 1 + iota
   367  	R_ADDRPOWER
   368  	R_ADDRARM64
   369  	R_SIZE
   370  	R_CALL
   371  	R_CALLARM
   372  	R_CALLARM64
   373  	R_CALLIND
   374  	R_CALLPOWER
   375  	R_CONST
   376  	R_PCREL
   377  	R_TLS
   378  	R_TLS_LE
   379  	R_TLS_IE
   380  	R_GOTOFF
   381  	R_PLT0
   382  	R_PLT1
   383  	R_PLT2
   384  	R_USEFIELD
   385  	R_POWER_TOC
   386  	R_GOTPCREL
   387  )
   388  
   389  type Auto struct {
   390  	Asym    *LSym
   391  	Link    *Auto
   392  	Aoffset int32
   393  	Name    int16
   394  	Gotype  *LSym
   395  }
   396  
   397  // Auto.name
   398  const (
   399  	A_AUTO = 1 + iota
   400  	A_PARAM
   401  )
   402  
   403  type Pcdata struct {
   404  	P []byte
   405  }
   406  
   407  // Pcdata iterator.
   408  //      for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
   409  type Pciter struct {
   410  	d       Pcdata
   411  	p       []byte
   412  	pc      uint32
   413  	nextpc  uint32
   414  	pcscale uint32
   415  	value   int32
   416  	start   int
   417  	done    int
   418  }
   419  
   420  // symbol version, incremented each time a file is loaded.
   421  // version==1 is reserved for savehist.
   422  const (
   423  	HistVersion = 1
   424  )
   425  
   426  // Link holds the context for writing object code from a compiler
   427  // to be linker input or for reading that input into the linker.
   428  type Link struct {
   429  	Goarm              int32
   430  	Headtype           int
   431  	Arch               *LinkArch
   432  	Debugasm           int32
   433  	Debugvlog          int32
   434  	Debugzerostack     int32
   435  	Debugdivmod        int32
   436  	Debugpcln          int32
   437  	Flag_shared        int32
   438  	Flag_dynlink       bool
   439  	Bso                *Biobuf
   440  	Pathname           string
   441  	Windows            int32
   442  	Trimpath           string
   443  	Goroot             string
   444  	Goroot_final       string
   445  	Enforce_data_order int32
   446  	Hash               map[SymVer]*LSym
   447  	LineHist           LineHist
   448  	Imports            []string
   449  	Plist              *Plist
   450  	Plast              *Plist
   451  	Sym_div            *LSym
   452  	Sym_divu           *LSym
   453  	Sym_mod            *LSym
   454  	Sym_modu           *LSym
   455  	Symmorestack       [2]*LSym
   456  	Tlsg               *LSym
   457  	Plan9privates      *LSym
   458  	Curp               *Prog
   459  	Printp             *Prog
   460  	Blitrl             *Prog
   461  	Elitrl             *Prog
   462  	Rexflag            int
   463  	Rep                int
   464  	Repn               int
   465  	Lock               int
   466  	Asmode             int
   467  	Andptr             []byte
   468  	And                [100]uint8
   469  	Instoffset         int64
   470  	Autosize           int32
   471  	Armsize            int32
   472  	Pc                 int64
   473  	Tlsoffset          int
   474  	Diag               func(string, ...interface{})
   475  	Mode               int
   476  	Cursym             *LSym
   477  	Version            int
   478  	Textp              *LSym
   479  	Etextp             *LSym
   480  }
   481  
   482  type SymVer struct {
   483  	Name    string
   484  	Version int
   485  }
   486  
   487  // LinkArch is the definition of a single architecture.
   488  type LinkArch struct {
   489  	ByteOrder  binary.ByteOrder
   490  	Name       string
   491  	Thechar    int
   492  	Preprocess func(*Link, *LSym)
   493  	Assemble   func(*Link, *LSym)
   494  	Follow     func(*Link, *LSym)
   495  	Progedit   func(*Link, *Prog)
   496  	UnaryDst   map[int]bool // Instruction takes one operand, a destination.
   497  	Minlc      int
   498  	Ptrsize    int
   499  	Regsize    int
   500  }
   501  
   502  /* executable header types */
   503  const (
   504  	Hunknown = 0 + iota
   505  	Hdarwin
   506  	Hdragonfly
   507  	Helf
   508  	Hfreebsd
   509  	Hlinux
   510  	Hnacl
   511  	Hnetbsd
   512  	Hopenbsd
   513  	Hplan9
   514  	Hsolaris
   515  	Hwindows
   516  )
   517  
   518  type Plist struct {
   519  	Name    *LSym
   520  	Firstpc *Prog
   521  	Recur   int
   522  	Link    *Plist
   523  }
   524  
   525  /*
   526   * start a new Prog list.
   527   */
   528  func Linknewplist(ctxt *Link) *Plist {
   529  	pl := new(Plist)
   530  	*pl = Plist{}
   531  	if ctxt.Plist == nil {
   532  		ctxt.Plist = pl
   533  	} else {
   534  		ctxt.Plast.Link = pl
   535  	}
   536  	ctxt.Plast = pl
   537  
   538  	return pl
   539  }