github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/internal/obj/link.go (about)

     1  // Derived from Inferno utils/6l/l.h and related files.
     2  // https://bitbucket.org/inferno-os/inferno-os/src/master/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 (
    34  	"bufio"
    35  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/dwarf"
    36  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/goobj"
    37  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/objabi"
    38  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/src"
    39  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/sys"
    40  	"encoding/binary"
    41  	"fmt"
    42  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/abi"
    43  	"sync"
    44  	"sync/atomic"
    45  )
    46  
    47  
    48  
    49  
    50  
    51  
    52  
    53  
    54  
    55  
    56  
    57  
    58  
    59  
    60  
    61  
    62  
    63  
    64  
    65  
    66  
    67  
    68  
    69  
    70  
    71  
    72  
    73  
    74  
    75  
    76  
    77  
    78  
    79  
    80  
    81  
    82  
    83  
    84  
    85  
    86  
    87  
    88  
    89  
    90  
    91  
    92  
    93  
    94  
    95  
    96  
    97  
    98  
    99  
   100  
   101  
   102  
   103  
   104  
   105  
   106  
   107  
   108  
   109  
   110  
   111  
   112  
   113  
   114  
   115  
   116  
   117  
   118  
   119  
   120  
   121  
   122  
   123  
   124  
   125  
   126  
   127  
   128  
   129  
   130  
   131  
   132  
   133  
   134  
   135  
   136  
   137  
   138  
   139  
   140  
   141  
   142  
   143  
   144  
   145  
   146  
   147  
   148  
   149  
   150  
   151  
   152  
   153  
   154  
   155  
   156  
   157  
   158  
   159  
   160  
   161  
   162  
   163  
   164  
   165  
   166  
   167  
   168  
   169  
   170  
   171  
   172  
   173  
   174  
   175  
   176  
   177  
   178  
   179  
   180  
   181  
   182  
   183  
   184  
   185  
   186  
   187  
   188  
   189  
   190  
   191  
   192  
   193  
   194  
   195  type Addr struct {
   196  	Reg    int16
   197  	Index  int16
   198  	Scale  int16 
   199  	Type   AddrType
   200  	Name   AddrName
   201  	Class  int8
   202  	Offset int64
   203  	Sym    *LSym
   204  
   205  	
   206  	
   207  	
   208  	
   209  	
   210  	Val interface{}
   211  }
   212  
   213  type AddrName int8
   214  
   215  const (
   216  	NAME_NONE AddrName = iota
   217  	NAME_EXTERN
   218  	NAME_STATIC
   219  	NAME_AUTO
   220  	NAME_PARAM
   221  	
   222  	
   223  	NAME_GOTREF
   224  	
   225  	NAME_TOCREF
   226  )
   227  
   228  //go:generate stringer -type AddrType
   229  
   230  type AddrType uint8
   231  
   232  const (
   233  	TYPE_NONE AddrType = iota
   234  	TYPE_BRANCH
   235  	TYPE_TEXTSIZE
   236  	TYPE_MEM
   237  	TYPE_CONST
   238  	TYPE_FCONST
   239  	TYPE_SCONST
   240  	TYPE_REG
   241  	TYPE_ADDR
   242  	TYPE_SHIFT
   243  	TYPE_REGREG
   244  	TYPE_REGREG2
   245  	TYPE_INDIR
   246  	TYPE_REGLIST
   247  	TYPE_SPECIAL
   248  )
   249  
   250  func (a *Addr) Target() *Prog {
   251  	if a.Type == TYPE_BRANCH && a.Val != nil {
   252  		return a.Val.(*Prog)
   253  	}
   254  	return nil
   255  }
   256  func (a *Addr) SetTarget(t *Prog) {
   257  	if a.Type != TYPE_BRANCH {
   258  		panic("setting branch target when type is not TYPE_BRANCH")
   259  	}
   260  	a.Val = t
   261  }
   262  
   263  func (a *Addr) SetConst(v int64) {
   264  	a.Sym = nil
   265  	a.Type = TYPE_CONST
   266  	a.Offset = v
   267  }
   268  
   269  
   270  
   271  
   272  
   273  
   274  
   275  
   276  
   277  
   278  
   279  
   280  
   281  
   282  
   283  
   284  
   285  
   286  
   287  
   288  
   289  
   290  
   291  
   292  
   293  
   294  
   295  
   296  
   297  
   298  
   299  
   300  type Prog struct {
   301  	Ctxt     *Link     
   302  	Link     *Prog     
   303  	From     Addr      
   304  	RestArgs []AddrPos 
   305  	To       Addr      
   306  	Pool     *Prog     
   307  	Forwd    *Prog     
   308  	Rel      *Prog     
   309  	Pc       int64     
   310  	Pos      src.XPos  
   311  	Spadj    int32     
   312  	As       As        
   313  	Reg      int16     
   314  	RegTo2   int16     
   315  	Mark     uint16    
   316  	Optab    uint16    
   317  	Scond    uint8     
   318  	Back     uint8     
   319  	Ft       uint8     
   320  	Tt       uint8     
   321  	Isize    uint8     
   322  }
   323  
   324  
   325  type AddrPos struct {
   326  	Addr
   327  	Pos OperandPos
   328  }
   329  
   330  type OperandPos int8
   331  
   332  const (
   333  	Source OperandPos = iota
   334  	Destination
   335  )
   336  
   337  
   338  
   339  
   340  
   341  func (p *Prog) From3Type() AddrType {
   342  	if p.RestArgs == nil {
   343  		return TYPE_NONE
   344  	}
   345  	return p.RestArgs[0].Type
   346  }
   347  
   348  
   349  
   350  
   351  
   352  
   353  
   354  
   355  
   356  
   357  func (p *Prog) GetFrom3() *Addr {
   358  	if p.RestArgs == nil {
   359  		return nil
   360  	}
   361  	return &p.RestArgs[0].Addr
   362  }
   363  
   364  
   365  
   366  
   367  
   368  func (p *Prog) SetFrom3(a Addr) {
   369  	p.RestArgs = []AddrPos{{a, Source}}
   370  }
   371  
   372  
   373  
   374  
   375  func (p *Prog) SetFrom3Reg(reg int16) {
   376  	p.SetFrom3(Addr{Type: TYPE_REG, Reg: reg})
   377  }
   378  
   379  
   380  
   381  
   382  func (p *Prog) SetFrom3Const(off int64) {
   383  	p.SetFrom3(Addr{Type: TYPE_CONST, Offset: off})
   384  }
   385  
   386  
   387  
   388  func (p *Prog) SetTo2(a Addr) {
   389  	p.RestArgs = []AddrPos{{a, Destination}}
   390  }
   391  
   392  
   393  func (p *Prog) GetTo2() *Addr {
   394  	if p.RestArgs == nil {
   395  		return nil
   396  	}
   397  	return &p.RestArgs[0].Addr
   398  }
   399  
   400  
   401  func (p *Prog) SetRestArgs(args []Addr) {
   402  	for i := range args {
   403  		p.RestArgs = append(p.RestArgs, AddrPos{args[i], Source})
   404  	}
   405  }
   406  
   407  
   408  
   409  
   410  
   411  
   412  type As int16
   413  
   414  
   415  const (
   416  	AXXX As = iota
   417  	ACALL
   418  	ADUFFCOPY
   419  	ADUFFZERO
   420  	AEND
   421  	AFUNCDATA
   422  	AJMP
   423  	ANOP
   424  	APCALIGN
   425  	APCDATA
   426  	ARET
   427  	AGETCALLERPC
   428  	ATEXT
   429  	AUNDEF
   430  	A_ARCHSPECIFIC
   431  )
   432  
   433  
   434  
   435  
   436  
   437  
   438  
   439  
   440  const (
   441  	ABase386 = (1 + iota) << 11
   442  	ABaseARM
   443  	ABaseAMD64
   444  	ABasePPC64
   445  	ABaseARM64
   446  	ABaseMIPS
   447  	ABaseLoong64
   448  	ABaseRISCV
   449  	ABaseS390X
   450  	ABaseWasm
   451  
   452  	AllowedOpCodes = 1 << 11            
   453  	AMask          = AllowedOpCodes - 1 
   454  )
   455  
   456  
   457  
   458  type LSym struct {
   459  	Name string
   460  	Type objabi.SymKind
   461  	Attribute
   462  
   463  	Size   int64
   464  	Gotype *LSym
   465  	P      []byte
   466  	R      []Reloc
   467  
   468  	Extra *interface{} 
   469  
   470  	Pkg    string
   471  	PkgIdx int32
   472  	SymIdx int32
   473  }
   474  
   475  
   476  type FuncInfo struct {
   477  	Args      int32
   478  	Locals    int32
   479  	Align     int32
   480  	FuncID    abi.FuncID
   481  	FuncFlag  abi.FuncFlag
   482  	StartLine int32
   483  	Text      *Prog
   484  	Autot     map[*LSym]struct{}
   485  	Pcln      Pcln
   486  	InlMarks  []InlMark
   487  	spills    []RegSpill
   488  
   489  	dwarfInfoSym       *LSym
   490  	dwarfLocSym        *LSym
   491  	dwarfRangesSym     *LSym
   492  	dwarfAbsFnSym      *LSym
   493  	dwarfDebugLinesSym *LSym
   494  
   495  	GCArgs             *LSym
   496  	GCLocals           *LSym
   497  	StackObjects       *LSym
   498  	OpenCodedDeferInfo *LSym
   499  	ArgInfo            *LSym 
   500  	ArgLiveInfo        *LSym 
   501  	WrapInfo           *LSym 
   502  	JumpTables         []JumpTable
   503  
   504  	FuncInfoSym   *LSym
   505  	WasmImportSym *LSym
   506  	WasmImport    *WasmImport
   507  
   508  	sehUnwindInfoSym *LSym
   509  }
   510  
   511  
   512  
   513  
   514  
   515  type JumpTable struct {
   516  	Sym     *LSym
   517  	Targets []*Prog
   518  }
   519  
   520  
   521  func (s *LSym) NewFuncInfo() *FuncInfo {
   522  	if s.Extra != nil {
   523  		panic(fmt.Sprintf("invalid use of LSym - NewFuncInfo with Extra of type %T", *s.Extra))
   524  	}
   525  	f := new(FuncInfo)
   526  	s.Extra = new(interface{})
   527  	*s.Extra = f
   528  	return f
   529  }
   530  
   531  
   532  func (s *LSym) Func() *FuncInfo {
   533  	if s.Extra == nil {
   534  		return nil
   535  	}
   536  	f, _ := (*s.Extra).(*FuncInfo)
   537  	return f
   538  }
   539  
   540  type VarInfo struct {
   541  	dwarfInfoSym *LSym
   542  }
   543  
   544  
   545  func (s *LSym) NewVarInfo() *VarInfo {
   546  	if s.Extra != nil {
   547  		panic(fmt.Sprintf("invalid use of LSym - NewVarInfo with Extra of type %T", *s.Extra))
   548  	}
   549  	f := new(VarInfo)
   550  	s.Extra = new(interface{})
   551  	*s.Extra = f
   552  	return f
   553  }
   554  
   555  
   556  func (s *LSym) VarInfo() *VarInfo {
   557  	if s.Extra == nil {
   558  		return nil
   559  	}
   560  	f, _ := (*s.Extra).(*VarInfo)
   561  	return f
   562  }
   563  
   564  
   565  
   566  type FileInfo struct {
   567  	Name string 
   568  	Size int64  
   569  }
   570  
   571  
   572  func (s *LSym) NewFileInfo() *FileInfo {
   573  	if s.Extra != nil {
   574  		panic(fmt.Sprintf("invalid use of LSym - NewFileInfo with Extra of type %T", *s.Extra))
   575  	}
   576  	f := new(FileInfo)
   577  	s.Extra = new(interface{})
   578  	*s.Extra = f
   579  	return f
   580  }
   581  
   582  
   583  func (s *LSym) File() *FileInfo {
   584  	if s.Extra == nil {
   585  		return nil
   586  	}
   587  	f, _ := (*s.Extra).(*FileInfo)
   588  	return f
   589  }
   590  
   591  
   592  
   593  type TypeInfo struct {
   594  	Type interface{} 
   595  }
   596  
   597  func (s *LSym) NewTypeInfo() *TypeInfo {
   598  	if s.Extra != nil {
   599  		panic(fmt.Sprintf("invalid use of LSym - NewTypeInfo with Extra of type %T", *s.Extra))
   600  	}
   601  	t := new(TypeInfo)
   602  	s.Extra = new(interface{})
   603  	*s.Extra = t
   604  	return t
   605  }
   606  
   607  
   608  
   609  
   610  type WasmImport struct {
   611  	
   612  	
   613  	Module string
   614  	
   615  	
   616  	Name string
   617  	
   618  	Params []WasmField
   619  	
   620  	Results []WasmField
   621  }
   622  
   623  func (wi *WasmImport) CreateSym(ctxt *Link) *LSym {
   624  	var sym LSym
   625  
   626  	var b [8]byte
   627  	writeByte := func(x byte) {
   628  		sym.WriteBytes(ctxt, sym.Size, []byte{x})
   629  	}
   630  	writeUint32 := func(x uint32) {
   631  		binary.LittleEndian.PutUint32(b[:], x)
   632  		sym.WriteBytes(ctxt, sym.Size, b[:4])
   633  	}
   634  	writeInt64 := func(x int64) {
   635  		binary.LittleEndian.PutUint64(b[:], uint64(x))
   636  		sym.WriteBytes(ctxt, sym.Size, b[:])
   637  	}
   638  	writeString := func(s string) {
   639  		writeUint32(uint32(len(s)))
   640  		sym.WriteString(ctxt, sym.Size, len(s), s)
   641  	}
   642  	writeString(wi.Module)
   643  	writeString(wi.Name)
   644  	writeUint32(uint32(len(wi.Params)))
   645  	for _, f := range wi.Params {
   646  		writeByte(byte(f.Type))
   647  		writeInt64(f.Offset)
   648  	}
   649  	writeUint32(uint32(len(wi.Results)))
   650  	for _, f := range wi.Results {
   651  		writeByte(byte(f.Type))
   652  		writeInt64(f.Offset)
   653  	}
   654  
   655  	return &sym
   656  }
   657  
   658  type WasmField struct {
   659  	Type WasmFieldType
   660  	
   661  	
   662  	
   663  	Offset int64
   664  }
   665  
   666  type WasmFieldType byte
   667  
   668  const (
   669  	WasmI32 WasmFieldType = iota
   670  	WasmI64
   671  	WasmF32
   672  	WasmF64
   673  	WasmPtr
   674  )
   675  
   676  type InlMark struct {
   677  	
   678  	
   679  	
   680  	
   681  	p  *Prog
   682  	id int32
   683  }
   684  
   685  
   686  
   687  
   688  
   689  func (fi *FuncInfo) AddInlMark(p *Prog, id int32) {
   690  	fi.InlMarks = append(fi.InlMarks, InlMark{p: p, id: id})
   691  }
   692  
   693  
   694  func (fi *FuncInfo) AddSpill(s RegSpill) {
   695  	fi.spills = append(fi.spills, s)
   696  }
   697  
   698  
   699  
   700  func (fi *FuncInfo) RecordAutoType(gotype *LSym) {
   701  	if fi.Autot == nil {
   702  		fi.Autot = make(map[*LSym]struct{})
   703  	}
   704  	fi.Autot[gotype] = struct{}{}
   705  }
   706  
   707  //go:generate stringer -type ABI
   708  
   709  
   710  type ABI uint8
   711  
   712  const (
   713  	
   714  	
   715  	
   716  	
   717  	
   718  	ABI0 ABI = iota
   719  
   720  	
   721  	
   722  	
   723  	
   724  	ABIInternal
   725  
   726  	ABICount
   727  )
   728  
   729  
   730  
   731  
   732  func ParseABI(abistr string) (ABI, bool) {
   733  	switch abistr {
   734  	default:
   735  		return ABI0, false
   736  	case "ABI0":
   737  		return ABI0, true
   738  	case "ABIInternal":
   739  		return ABIInternal, true
   740  	}
   741  }
   742  
   743  
   744  type ABISet uint8
   745  
   746  const (
   747  	
   748  	
   749  	ABISetCallable ABISet = (1 << ABI0) | (1 << ABIInternal)
   750  )
   751  
   752  
   753  var _ ABISet = 1 << (ABICount - 1)
   754  
   755  func ABISetOf(abi ABI) ABISet {
   756  	return 1 << abi
   757  }
   758  
   759  func (a *ABISet) Set(abi ABI, value bool) {
   760  	if value {
   761  		*a |= 1 << abi
   762  	} else {
   763  		*a &^= 1 << abi
   764  	}
   765  }
   766  
   767  func (a *ABISet) Get(abi ABI) bool {
   768  	return (*a>>abi)&1 != 0
   769  }
   770  
   771  func (a ABISet) String() string {
   772  	s := "{"
   773  	for i := ABI(0); a != 0; i++ {
   774  		if a&(1<<i) != 0 {
   775  			if s != "{" {
   776  				s += ","
   777  			}
   778  			s += i.String()
   779  			a &^= 1 << i
   780  		}
   781  	}
   782  	return s + "}"
   783  }
   784  
   785  
   786  type Attribute uint32
   787  
   788  const (
   789  	AttrDuplicateOK Attribute = 1 << iota
   790  	AttrCFunc
   791  	AttrNoSplit
   792  	AttrLeaf
   793  	AttrWrapper
   794  	AttrNeedCtxt
   795  	AttrNoFrame
   796  	AttrOnList
   797  	AttrStatic
   798  
   799  	
   800  	AttrMakeTypelink
   801  
   802  	
   803  	
   804  	
   805  	
   806  	
   807  	
   808  	AttrReflectMethod
   809  
   810  	
   811  	
   812  	
   813  	
   814  	
   815  	
   816  	AttrLocal
   817  
   818  	
   819  	
   820  	AttrWasInlined
   821  
   822  	
   823  	
   824  	AttrIndexed
   825  
   826  	
   827  	
   828  	
   829  	
   830  	AttrUsedInIface
   831  
   832  	
   833  	AttrContentAddressable
   834  
   835  	
   836  	
   837  	AttrABIWrapper
   838  
   839  	
   840  	AttrPcdata
   841  
   842  	
   843  	AttrPkgInit
   844  
   845  	
   846  	
   847  	
   848  	
   849  	
   850  	attrABIBase
   851  )
   852  
   853  func (a *Attribute) load() Attribute { return Attribute(atomic.LoadUint32((*uint32)(a))) }
   854  
   855  func (a *Attribute) DuplicateOK() bool        { return a.load()&AttrDuplicateOK != 0 }
   856  func (a *Attribute) MakeTypelink() bool       { return a.load()&AttrMakeTypelink != 0 }
   857  func (a *Attribute) CFunc() bool              { return a.load()&AttrCFunc != 0 }
   858  func (a *Attribute) NoSplit() bool            { return a.load()&AttrNoSplit != 0 }
   859  func (a *Attribute) Leaf() bool               { return a.load()&AttrLeaf != 0 }
   860  func (a *Attribute) OnList() bool             { return a.load()&AttrOnList != 0 }
   861  func (a *Attribute) ReflectMethod() bool      { return a.load()&AttrReflectMethod != 0 }
   862  func (a *Attribute) Local() bool              { return a.load()&AttrLocal != 0 }
   863  func (a *Attribute) Wrapper() bool            { return a.load()&AttrWrapper != 0 }
   864  func (a *Attribute) NeedCtxt() bool           { return a.load()&AttrNeedCtxt != 0 }
   865  func (a *Attribute) NoFrame() bool            { return a.load()&AttrNoFrame != 0 }
   866  func (a *Attribute) Static() bool             { return a.load()&AttrStatic != 0 }
   867  func (a *Attribute) WasInlined() bool         { return a.load()&AttrWasInlined != 0 }
   868  func (a *Attribute) Indexed() bool            { return a.load()&AttrIndexed != 0 }
   869  func (a *Attribute) UsedInIface() bool        { return a.load()&AttrUsedInIface != 0 }
   870  func (a *Attribute) ContentAddressable() bool { return a.load()&AttrContentAddressable != 0 }
   871  func (a *Attribute) ABIWrapper() bool         { return a.load()&AttrABIWrapper != 0 }
   872  func (a *Attribute) IsPcdata() bool           { return a.load()&AttrPcdata != 0 }
   873  func (a *Attribute) IsPkgInit() bool          { return a.load()&AttrPkgInit != 0 }
   874  
   875  func (a *Attribute) Set(flag Attribute, value bool) {
   876  	for {
   877  		v0 := a.load()
   878  		v := v0
   879  		if value {
   880  			v |= flag
   881  		} else {
   882  			v &^= flag
   883  		}
   884  		if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
   885  			break
   886  		}
   887  	}
   888  }
   889  
   890  func (a *Attribute) ABI() ABI { return ABI(a.load() / attrABIBase) }
   891  func (a *Attribute) SetABI(abi ABI) {
   892  	const mask = 1 
   893  	for {
   894  		v0 := a.load()
   895  		v := (v0 &^ (mask * attrABIBase)) | Attribute(abi)*attrABIBase
   896  		if atomic.CompareAndSwapUint32((*uint32)(a), uint32(v0), uint32(v)) {
   897  			break
   898  		}
   899  	}
   900  }
   901  
   902  var textAttrStrings = [...]struct {
   903  	bit Attribute
   904  	s   string
   905  }{
   906  	{bit: AttrDuplicateOK, s: "DUPOK"},
   907  	{bit: AttrMakeTypelink, s: ""},
   908  	{bit: AttrCFunc, s: "CFUNC"},
   909  	{bit: AttrNoSplit, s: "NOSPLIT"},
   910  	{bit: AttrLeaf, s: "LEAF"},
   911  	{bit: AttrOnList, s: ""},
   912  	{bit: AttrReflectMethod, s: "REFLECTMETHOD"},
   913  	{bit: AttrLocal, s: "LOCAL"},
   914  	{bit: AttrWrapper, s: "WRAPPER"},
   915  	{bit: AttrNeedCtxt, s: "NEEDCTXT"},
   916  	{bit: AttrNoFrame, s: "NOFRAME"},
   917  	{bit: AttrStatic, s: "STATIC"},
   918  	{bit: AttrWasInlined, s: ""},
   919  	{bit: AttrIndexed, s: ""},
   920  	{bit: AttrContentAddressable, s: ""},
   921  	{bit: AttrABIWrapper, s: "ABIWRAPPER"},
   922  	{bit: AttrPkgInit, s: "PKGINIT"},
   923  }
   924  
   925  
   926  func (a Attribute) String() string {
   927  	var s string
   928  	for _, x := range textAttrStrings {
   929  		if a&x.bit != 0 {
   930  			if x.s != "" {
   931  				s += x.s + "|"
   932  			}
   933  			a &^= x.bit
   934  		}
   935  	}
   936  	switch a.ABI() {
   937  	case ABI0:
   938  	case ABIInternal:
   939  		s += "ABIInternal|"
   940  		a.SetABI(0) 
   941  	}
   942  	if a != 0 {
   943  		s += fmt.Sprintf("UnknownAttribute(%d)|", a)
   944  	}
   945  	
   946  	if len(s) > 0 {
   947  		s = s[:len(s)-1]
   948  	}
   949  	return s
   950  }
   951  
   952  
   953  func (s *LSym) TextAttrString() string {
   954  	attr := s.Attribute.String()
   955  	if s.Func().FuncFlag&abi.FuncFlagTopFrame != 0 {
   956  		if attr != "" {
   957  			attr += "|"
   958  		}
   959  		attr += "TOPFRAME"
   960  	}
   961  	return attr
   962  }
   963  
   964  func (s *LSym) String() string {
   965  	return s.Name
   966  }
   967  
   968  
   969  func (*LSym) CanBeAnSSASym() {}
   970  func (*LSym) CanBeAnSSAAux() {}
   971  
   972  type Pcln struct {
   973  	
   974  	Pcsp      *LSym
   975  	Pcfile    *LSym
   976  	Pcline    *LSym
   977  	Pcinline  *LSym
   978  	Pcdata    []*LSym
   979  	Funcdata  []*LSym
   980  	UsedFiles map[goobj.CUFileIndex]struct{} 
   981  	InlTree   InlTree                        
   982  }
   983  
   984  type Reloc struct {
   985  	Off  int32
   986  	Siz  uint8
   987  	Type objabi.RelocType
   988  	Add  int64
   989  	Sym  *LSym
   990  }
   991  
   992  type Auto struct {
   993  	Asym    *LSym
   994  	Aoffset int32
   995  	Name    AddrName
   996  	Gotype  *LSym
   997  }
   998  
   999  
  1000  
  1001  
  1002  
  1003  
  1004  type RegSpill struct {
  1005  	Addr           Addr
  1006  	Reg            int16
  1007  	Spill, Unspill As
  1008  }
  1009  
  1010  
  1011  
  1012  type Link struct {
  1013  	Headtype           objabi.HeadType
  1014  	Arch               *LinkArch
  1015  	Debugasm           int
  1016  	Debugvlog          bool
  1017  	Debugpcln          string
  1018  	Flag_shared        bool
  1019  	Flag_dynlink       bool
  1020  	Flag_linkshared    bool
  1021  	Flag_optimize      bool
  1022  	Flag_locationlists bool
  1023  	Flag_noRefName     bool   
  1024  	Retpoline          bool   
  1025  	Flag_maymorestack  string 
  1026  	Bso                *bufio.Writer
  1027  	Pathname           string
  1028  	Pkgpath            string           
  1029  	hashmu             sync.Mutex       
  1030  	hash               map[string]*LSym 
  1031  	funchash           map[string]*LSym 
  1032  	statichash         map[string]*LSym 
  1033  	PosTable           src.PosTable
  1034  	InlTree            InlTree 
  1035  	DwFixups           *DwarfFixupTable
  1036  	Imports            []goobj.ImportedPkg
  1037  	DiagFunc           func(string, ...interface{})
  1038  	DiagFlush          func()
  1039  	DebugInfo          func(fn *LSym, info *LSym, curfn interface{}) ([]dwarf.Scope, dwarf.InlCalls, src.XPos) 
  1040  	GenAbstractFunc    func(fn *LSym)
  1041  	Errors             int
  1042  
  1043  	InParallel    bool 
  1044  	UseBASEntries bool 
  1045  	IsAsm         bool 
  1046  
  1047  	
  1048  	Text []*LSym
  1049  	Data []*LSym
  1050  
  1051  	
  1052  	
  1053  	
  1054  	
  1055  	constSyms []*LSym
  1056  
  1057  	
  1058  	
  1059  	pkgIdx map[string]int32
  1060  
  1061  	defs         []*LSym 
  1062  	hashed64defs []*LSym 
  1063  	hasheddefs   []*LSym 
  1064  	nonpkgdefs   []*LSym 
  1065  	nonpkgrefs   []*LSym 
  1066  
  1067  	Fingerprint goobj.FingerprintType 
  1068  }
  1069  
  1070  func (ctxt *Link) Diag(format string, args ...interface{}) {
  1071  	ctxt.Errors++
  1072  	ctxt.DiagFunc(format, args...)
  1073  }
  1074  
  1075  func (ctxt *Link) Logf(format string, args ...interface{}) {
  1076  	fmt.Fprintf(ctxt.Bso, format, args...)
  1077  	ctxt.Bso.Flush()
  1078  }
  1079  
  1080  
  1081  
  1082  func (fi *FuncInfo) SpillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
  1083  	
  1084  	for _, ra := range fi.spills {
  1085  		spill := Appendp(last, pa)
  1086  		spill.As = ra.Spill
  1087  		spill.From.Type = TYPE_REG
  1088  		spill.From.Reg = ra.Reg
  1089  		spill.To = ra.Addr
  1090  		last = spill
  1091  	}
  1092  	return last
  1093  }
  1094  
  1095  
  1096  
  1097  func (fi *FuncInfo) UnspillRegisterArgs(last *Prog, pa ProgAlloc) *Prog {
  1098  	
  1099  	for _, ra := range fi.spills {
  1100  		unspill := Appendp(last, pa)
  1101  		unspill.As = ra.Unspill
  1102  		unspill.From = ra.Addr
  1103  		unspill.To.Type = TYPE_REG
  1104  		unspill.To.Reg = ra.Reg
  1105  		last = unspill
  1106  	}
  1107  	return last
  1108  }
  1109  
  1110  
  1111  type LinkArch struct {
  1112  	*sys.Arch
  1113  	Init           func(*Link)
  1114  	ErrorCheck     func(*Link, *LSym)
  1115  	Preprocess     func(*Link, *LSym, ProgAlloc)
  1116  	Assemble       func(*Link, *LSym, ProgAlloc)
  1117  	Progedit       func(*Link, *Prog, ProgAlloc)
  1118  	SEH            func(*Link, *LSym) *LSym
  1119  	UnaryDst       map[As]bool 
  1120  	DWARFRegisters map[int16]int16
  1121  }