github.com/aloncn/graphics-go@v0.0.1/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  	Index  int16
   150  	Scale  int16 // Sometimes holds a register.
   151  	Name   int8
   152  	Class  int8
   153  	Etype  uint8
   154  	Offset int64
   155  	Width  int64
   156  	Sym    *LSym
   157  	Gotype *LSym
   158  
   159  	// argument value:
   160  	//	for TYPE_SCONST, a string
   161  	//	for TYPE_FCONST, a float64
   162  	//	for TYPE_BRANCH, a *Prog (optional)
   163  	//	for TYPE_TEXTSIZE, an int32 (optional)
   164  	Val interface{}
   165  
   166  	Node interface{} // for use by compiler
   167  }
   168  
   169  const (
   170  	NAME_NONE = 0 + iota
   171  	NAME_EXTERN
   172  	NAME_STATIC
   173  	NAME_AUTO
   174  	NAME_PARAM
   175  	// A reference to name@GOT(SB) is a reference to the entry in the global offset
   176  	// table for 'name'.
   177  	NAME_GOTREF
   178  )
   179  
   180  const (
   181  	TYPE_NONE = 0
   182  )
   183  
   184  const (
   185  	TYPE_BRANCH = 5 + iota
   186  	TYPE_TEXTSIZE
   187  	TYPE_MEM
   188  	TYPE_CONST
   189  	TYPE_FCONST
   190  	TYPE_SCONST
   191  	TYPE_REG
   192  	TYPE_ADDR
   193  	TYPE_SHIFT
   194  	TYPE_REGREG
   195  	TYPE_REGREG2
   196  	TYPE_INDIR
   197  	TYPE_REGLIST
   198  )
   199  
   200  // TODO(rsc): Describe prog.
   201  // TODO(rsc): Describe TEXT/GLOBL flag in from3, DATA width in from3.
   202  type Prog struct {
   203  	Ctxt   *Link
   204  	Link   *Prog
   205  	From   Addr
   206  	From3  *Addr // optional
   207  	To     Addr
   208  	Opt    interface{}
   209  	Forwd  *Prog
   210  	Pcond  *Prog
   211  	Rel    *Prog // Source of forward jumps on x86; pcrel on arm
   212  	Pc     int64
   213  	Lineno int32
   214  	Spadj  int32
   215  	As     int16
   216  	Reg    int16
   217  	RegTo2 int16 // 2nd register output operand
   218  	Mark   uint16
   219  	Optab  uint16
   220  	Scond  uint8
   221  	Back   uint8
   222  	Ft     uint8
   223  	Tt     uint8
   224  	Isize  uint8
   225  	Mode   int8
   226  
   227  	Info ProgInfo
   228  }
   229  
   230  // From3Type returns From3.Type, or TYPE_NONE when From3 is nil.
   231  func (p *Prog) From3Type() int16 {
   232  	if p.From3 == nil {
   233  		return TYPE_NONE
   234  	}
   235  	return p.From3.Type
   236  }
   237  
   238  // From3Offset returns From3.Offset, or 0 when From3 is nil.
   239  func (p *Prog) From3Offset() int64 {
   240  	if p.From3 == nil {
   241  		return 0
   242  	}
   243  	return p.From3.Offset
   244  }
   245  
   246  // ProgInfo holds information about the instruction for use
   247  // by clients such as the compiler. The exact meaning of this
   248  // data is up to the client and is not interpreted by the cmd/internal/obj/... packages.
   249  type ProgInfo struct {
   250  	_        struct{} // to prevent unkeyed literals. Trailing zero-sized field will take space.
   251  	Flags    uint32   // flag bits
   252  	Reguse   uint64   // registers implicitly used by this instruction
   253  	Regset   uint64   // registers implicitly set by this instruction
   254  	Regindex uint64   // registers used by addressing mode
   255  }
   256  
   257  // Prog.as opcodes.
   258  // These are the portable opcodes, common to all architectures.
   259  // Each architecture defines many more arch-specific opcodes,
   260  // with values starting at A_ARCHSPECIFIC.
   261  // Each architecture adds an offset to this so each machine has
   262  // distinct space for its instructions. The offset is a power of
   263  // two so it can be masked to return to origin zero.
   264  // See the definitions of ABase386 etc.
   265  const (
   266  	AXXX = 0 + iota
   267  	ACALL
   268  	ACHECKNIL
   269  	ADATA
   270  	ADUFFCOPY
   271  	ADUFFZERO
   272  	AEND
   273  	AFUNCDATA
   274  	AGLOBL
   275  	AJMP
   276  	ANOP
   277  	APCDATA
   278  	ARET
   279  	ATEXT
   280  	ATYPE
   281  	AUNDEF
   282  	AUSEFIELD
   283  	AVARDEF
   284  	AVARKILL
   285  	AVARLIVE
   286  	A_ARCHSPECIFIC
   287  )
   288  
   289  // An LSym is the sort of symbol that is written to an object file.
   290  type LSym struct {
   291  	Name      string
   292  	Type      int16
   293  	Version   int16
   294  	Dupok     uint8
   295  	Cfunc     uint8
   296  	Nosplit   uint8
   297  	Leaf      uint8
   298  	Seenglobl uint8
   299  	Onlist    uint8
   300  	// Local means make the symbol local even when compiling Go code to reference Go
   301  	// symbols in other shared libraries, as in this mode symbols are global by
   302  	// default. "local" here means in the sense of the dynamic linker, i.e. not
   303  	// visible outside of the module (shared library or executable) that contains its
   304  	// definition. (When not compiling to support Go shared libraries, all symbols are
   305  	// local in this sense unless there is a cgo_export_* directive).
   306  	Local  bool
   307  	Args   int32
   308  	Locals int32
   309  	Value  int64
   310  	Size   int64
   311  	Next   *LSym
   312  	Gotype *LSym
   313  	Autom  *Auto
   314  	Text   *Prog
   315  	Etext  *Prog
   316  	Pcln   *Pcln
   317  	P      []byte
   318  	R      []Reloc
   319  }
   320  
   321  type Pcln struct {
   322  	Pcsp        Pcdata
   323  	Pcfile      Pcdata
   324  	Pcline      Pcdata
   325  	Pcdata      []Pcdata
   326  	Funcdata    []*LSym
   327  	Funcdataoff []int64
   328  	File        []*LSym
   329  	Lastfile    *LSym
   330  	Lastindex   int
   331  }
   332  
   333  // LSym.type
   334  const (
   335  	Sxxx = iota
   336  	STEXT
   337  	SELFRXSECT
   338  
   339  	STYPE
   340  	SSTRING
   341  	SGOSTRING
   342  	SGOFUNC
   343  	SGCBITS
   344  	SRODATA
   345  	SFUNCTAB
   346  
   347  	// Types STYPE-SFUNCTAB above are written to the .rodata section by default.
   348  	// When linking a shared object, some conceptually "read only" types need to
   349  	// be written to by relocations and putting them in a section called
   350  	// ".rodata" interacts poorly with the system linkers. The GNU linkers
   351  	// support this situation by arranging for sections of the name
   352  	// ".data.rel.ro.XXX" to be mprotected read only by the dynamic linker after
   353  	// relocations have applied, so when the Go linker is creating a shared
   354  	// object it checks all objects of the above types and bumps any object that
   355  	// has a relocation to it to the corresponding type below, which are then
   356  	// written to sections with appropriate magic names.
   357  	STYPERELRO
   358  	SSTRINGRELRO
   359  	SGOSTRINGRELRO
   360  	SGOFUNCRELRO
   361  	SGCBITSRELRO
   362  	SRODATARELRO
   363  	SFUNCTABRELRO
   364  
   365  	STYPELINK
   366  	SSYMTAB
   367  	SPCLNTAB
   368  	SELFROSECT
   369  	SMACHOPLT
   370  	SELFSECT
   371  	SMACHO
   372  	SMACHOGOT
   373  	SWINDOWS
   374  	SELFGOT
   375  	SNOPTRDATA
   376  	SINITARR
   377  	SDATA
   378  	SBSS
   379  	SNOPTRBSS
   380  	STLSBSS
   381  	SXREF
   382  	SMACHOSYMSTR
   383  	SMACHOSYMTAB
   384  	SMACHOINDIRECTPLT
   385  	SMACHOINDIRECTGOT
   386  	SFILE
   387  	SFILEPATH
   388  	SCONST
   389  	SDYNIMPORT
   390  	SHOSTOBJ
   391  	SSUB       = 1 << 8
   392  	SMASK      = SSUB - 1
   393  	SHIDDEN    = 1 << 9
   394  	SCONTAINER = 1 << 10 // has a sub-symbol
   395  )
   396  
   397  type Reloc struct {
   398  	Off  int32
   399  	Siz  uint8
   400  	Type int32
   401  	Add  int64
   402  	Sym  *LSym
   403  }
   404  
   405  // Reloc.type
   406  const (
   407  	R_ADDR = 1 + iota
   408  	// R_ADDRPOWER relocates a pair of "D-form" instructions (instructions with 16-bit
   409  	// immediates in the low half of the instruction word), usually addis followed by
   410  	// another add or a load, inserting the "high adjusted" 16 bits of the address of
   411  	// the referenced symbol into the immediate field of the first instruction and the
   412  	// low 16 bits into that of the second instruction.
   413  	R_ADDRPOWER
   414  	// R_ADDRARM64 relocates an adrp, add pair to compute the address of the
   415  	// referenced symbol.
   416  	R_ADDRARM64
   417  	// R_ADDRMIPS (only used on mips64) resolves to a 32-bit external address,
   418  	// by loading the address into a register with two instructions (lui, ori).
   419  	R_ADDRMIPS
   420  	R_SIZE
   421  	R_CALL
   422  	R_CALLARM
   423  	R_CALLARM64
   424  	R_CALLIND
   425  	R_CALLPOWER
   426  	// R_CALLMIPS (only used on mips64) resolves to non-PC-relative target address
   427  	// of a CALL (JAL) instruction, by encoding the address into the instruction.
   428  	R_CALLMIPS
   429  	R_CONST
   430  	R_PCREL
   431  	// R_TLS_LE, used on 386, amd64, and ARM, resolves to the offset of the
   432  	// thread-local symbol from the thread local base and is used to implement the
   433  	// "local exec" model for tls access (r.Sym is not set on intel platforms but is
   434  	// set to a TLS symbol -- runtime.tlsg -- in the linker when externally linking).
   435  	R_TLS_LE
   436  	// R_TLS_IE, used 386, amd64, and ARM resolves to the PC-relative offset to a GOT
   437  	// slot containing the offset from the thread-local symbol from the thread local
   438  	// base and is used to implemented the "initial exec" model for tls access (r.Sym
   439  	// is not set on intel platforms but is set to a TLS symbol -- runtime.tlsg -- in
   440  	// the linker when externally linking).
   441  	R_TLS_IE
   442  	R_GOTOFF
   443  	R_PLT0
   444  	R_PLT1
   445  	R_PLT2
   446  	R_USEFIELD
   447  	R_POWER_TOC
   448  	R_GOTPCREL
   449  	// R_JMPMIPS (only used on mips64) resolves to non-PC-relative target address
   450  	// of a JMP instruction, by encoding the address into the instruction.
   451  	// The stack nosplit check ignores this since it is not a function call.
   452  	R_JMPMIPS
   453  
   454  	// Platform dependent relocations. Architectures with fixed width instructions
   455  	// have the inherent issue that a 32-bit (or 64-bit!) displacement cannot be
   456  	// stuffed into a 32-bit instruction, so an address needs to be spread across
   457  	// several instructions, and in turn this requires a sequence of relocations, each
   458  	// updating a part of an instruction.  This leads to relocation codes that are
   459  	// inherently processor specific.
   460  
   461  	// Arm64.
   462  
   463  	// Set a MOV[NZ] immediate field to bits [15:0] of the offset from the thread
   464  	// local base to the thread local variable defined by the referenced (thread
   465  	// local) symbol. Error if the offset does not fit into 16 bits.
   466  	R_ARM64_TLS_LE
   467  
   468  	// Relocates an ADRP; LD64 instruction sequence to load the offset between
   469  	// the thread local base and the thread local variable defined by the
   470  	// referenced (thread local) symbol from the GOT.
   471  	R_ARM64_TLS_IE
   472  
   473  	// R_ARM64_GOTPCREL relocates an adrp, ld64 pair to compute the address of the GOT
   474  	// slot of the referenced symbol.
   475  	R_ARM64_GOTPCREL
   476  
   477  	// PPC64.
   478  
   479  	// R_POWER_TLS_LE is used to implement the "local exec" model for tls
   480  	// access. It resolves to the offset of the thread-local symbol from the
   481  	// thread pointer (R13) and inserts this value into the low 16 bits of an
   482  	// instruction word.
   483  	R_POWER_TLS_LE
   484  
   485  	// R_POWER_TLS_IE is used to implement the "initial exec" model for tls access. It
   486  	// relocates a D-form, DS-form instruction sequence like R_ADDRPOWER_DS. It
   487  	// inserts to the offset of GOT slot for the thread-local symbol from the TOC (the
   488  	// GOT slot is filled by the dynamic linker with the offset of the thread-local
   489  	// symbol from the thread pointer (R13)).
   490  	R_POWER_TLS_IE
   491  
   492  	// R_POWER_TLS marks an X-form instruction such as "MOVD 0(R13)(R31*1), g" as
   493  	// accessing a particular thread-local symbol. It does not affect code generation
   494  	// but is used by the system linker when relaxing "initial exec" model code to
   495  	// "local exec" model code.
   496  	R_POWER_TLS
   497  
   498  	// R_ADDRPOWER_DS is similar to R_ADDRPOWER above, but assumes the second
   499  	// instruction is a "DS-form" instruction, which has an immediate field occupying
   500  	// bits [15:2] of the instruction word. Bits [15:2] of the address of the
   501  	// relocated symbol are inserted into this field; it is an error if the last two
   502  	// bits of the address are not 0.
   503  	R_ADDRPOWER_DS
   504  
   505  	// R_ADDRPOWER_PCREL relocates a D-form, DS-form instruction sequence like
   506  	// R_ADDRPOWER_DS but inserts the offset of the GOT slot for the referenced symbol
   507  	// from the TOC rather than the symbol's address.
   508  	R_ADDRPOWER_GOT
   509  
   510  	// R_ADDRPOWER_PCREL relocates two D-form instructions like R_ADDRPOWER, but
   511  	// inserts the displacement from the place being relocated to the address of the
   512  	// the relocated symbol instead of just its address.
   513  	R_ADDRPOWER_PCREL
   514  
   515  	// R_ADDRPOWER_TOCREL relocates two D-form instructions like R_ADDRPOWER, but
   516  	// inserts the offset from the TOC to the address of the the relocated symbol
   517  	// rather than the symbol's address.
   518  	R_ADDRPOWER_TOCREL
   519  
   520  	// R_ADDRPOWER_TOCREL relocates a D-form, DS-form instruction sequence like
   521  	// R_ADDRPOWER_DS but inserts the offset from the TOC to the address of the the
   522  	// relocated symbol rather than the symbol's address.
   523  	R_ADDRPOWER_TOCREL_DS
   524  )
   525  
   526  type Auto struct {
   527  	Asym    *LSym
   528  	Link    *Auto
   529  	Aoffset int32
   530  	Name    int16
   531  	Gotype  *LSym
   532  }
   533  
   534  // Auto.name
   535  const (
   536  	A_AUTO = 1 + iota
   537  	A_PARAM
   538  )
   539  
   540  type Pcdata struct {
   541  	P []byte
   542  }
   543  
   544  // Pcdata iterator.
   545  //      for(pciterinit(ctxt, &it, &pcd); !it.done; pciternext(&it)) { it.value holds in [it.pc, it.nextpc) }
   546  type Pciter struct {
   547  	d       Pcdata
   548  	p       []byte
   549  	pc      uint32
   550  	nextpc  uint32
   551  	pcscale uint32
   552  	value   int32
   553  	start   int
   554  	done    int
   555  }
   556  
   557  // symbol version, incremented each time a file is loaded.
   558  // version==1 is reserved for savehist.
   559  const (
   560  	HistVersion = 1
   561  )
   562  
   563  // Link holds the context for writing object code from a compiler
   564  // to be linker input or for reading that input into the linker.
   565  type Link struct {
   566  	Goarm              int32
   567  	Headtype           int
   568  	Arch               *LinkArch
   569  	Debugasm           int32
   570  	Debugvlog          int32
   571  	Debugdivmod        int32
   572  	Debugpcln          int32
   573  	Flag_shared        int32
   574  	Flag_dynlink       bool
   575  	Bso                *Biobuf
   576  	Pathname           string
   577  	Windows            int32
   578  	Goroot             string
   579  	Goroot_final       string
   580  	Enforce_data_order int32
   581  	Hash               map[SymVer]*LSym
   582  	LineHist           LineHist
   583  	Imports            []string
   584  	Plist              *Plist
   585  	Plast              *Plist
   586  	Sym_div            *LSym
   587  	Sym_divu           *LSym
   588  	Sym_mod            *LSym
   589  	Sym_modu           *LSym
   590  	Plan9privates      *LSym
   591  	Curp               *Prog
   592  	Printp             *Prog
   593  	Blitrl             *Prog
   594  	Elitrl             *Prog
   595  	Rexflag            int
   596  	Vexflag            int
   597  	Rep                int
   598  	Repn               int
   599  	Lock               int
   600  	Asmode             int
   601  	Andptr             []byte
   602  	And                [100]uint8
   603  	Instoffset         int64
   604  	Autosize           int32
   605  	Armsize            int32
   606  	Pc                 int64
   607  	DiagFunc           func(string, ...interface{})
   608  	Mode               int
   609  	Cursym             *LSym
   610  	Version            int
   611  	Textp              *LSym
   612  	Etextp             *LSym
   613  	Errors             int
   614  
   615  	// state for writing objects
   616  	Text  *LSym
   617  	Data  *LSym
   618  	Etext *LSym
   619  	Edata *LSym
   620  }
   621  
   622  func (ctxt *Link) Diag(format string, args ...interface{}) {
   623  	ctxt.Errors++
   624  	ctxt.DiagFunc(format, args...)
   625  }
   626  
   627  // The smallest possible offset from the hardware stack pointer to a local
   628  // variable on the stack. Architectures that use a link register save its value
   629  // on the stack in the function prologue and so always have a pointer between
   630  // the hardware stack pointer and the local variable area.
   631  func (ctxt *Link) FixedFrameSize() int64 {
   632  	switch ctxt.Arch.Thechar {
   633  	case '6', '8':
   634  		return 0
   635  	case '9':
   636  		// PIC code on ppc64le requires 32 bytes of stack, and it's easier to
   637  		// just use that much stack always on ppc64x.
   638  		return int64(4 * ctxt.Arch.Ptrsize)
   639  	default:
   640  		return int64(ctxt.Arch.Ptrsize)
   641  	}
   642  }
   643  
   644  type SymVer struct {
   645  	Name    string
   646  	Version int // TODO: make int16 to match LSym.Version?
   647  }
   648  
   649  // LinkArch is the definition of a single architecture.
   650  type LinkArch struct {
   651  	ByteOrder  binary.ByteOrder
   652  	Name       string
   653  	Thechar    int
   654  	Preprocess func(*Link, *LSym)
   655  	Assemble   func(*Link, *LSym)
   656  	Follow     func(*Link, *LSym)
   657  	Progedit   func(*Link, *Prog)
   658  	UnaryDst   map[int]bool // Instruction takes one operand, a destination.
   659  	Minlc      int
   660  	Ptrsize    int
   661  	Regsize    int
   662  }
   663  
   664  /* executable header types */
   665  const (
   666  	Hunknown = 0 + iota
   667  	Hdarwin
   668  	Hdragonfly
   669  	Helf
   670  	Hfreebsd
   671  	Hlinux
   672  	Hnacl
   673  	Hnetbsd
   674  	Hopenbsd
   675  	Hplan9
   676  	Hsolaris
   677  	Hwindows
   678  )
   679  
   680  type Plist struct {
   681  	Name    *LSym
   682  	Firstpc *Prog
   683  	Recur   int
   684  	Link    *Plist
   685  }
   686  
   687  /*
   688   * start a new Prog list.
   689   */
   690  func Linknewplist(ctxt *Link) *Plist {
   691  	pl := new(Plist)
   692  	if ctxt.Plist == nil {
   693  		ctxt.Plist = pl
   694  	} else {
   695  		ctxt.Plast.Link = pl
   696  	}
   697  	ctxt.Plast = pl
   698  	return pl
   699  }