github.com/sanprasirt/go@v0.0.0-20170607001320-a027466e4b6d/src/cmd/link/internal/ppc64/asm.go (about)

     1  // Inferno utils/5l/asm.c
     2  // https://bitbucket.org/inferno-os/inferno-os/src/default/utils/5l/asm.c
     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 ppc64
    32  
    33  import (
    34  	"cmd/internal/objabi"
    35  	"cmd/link/internal/ld"
    36  	"encoding/binary"
    37  	"fmt"
    38  	"log"
    39  )
    40  
    41  func genplt(ctxt *ld.Link) {
    42  	// The ppc64 ABI PLT has similar concepts to other
    43  	// architectures, but is laid out quite differently. When we
    44  	// see an R_PPC64_REL24 relocation to a dynamic symbol
    45  	// (indicating that the call needs to go through the PLT), we
    46  	// generate up to three stubs and reserve a PLT slot.
    47  	//
    48  	// 1) The call site will be bl x; nop (where the relocation
    49  	//    applies to the bl).  We rewrite this to bl x_stub; ld
    50  	//    r2,24(r1).  The ld is necessary because x_stub will save
    51  	//    r2 (the TOC pointer) at 24(r1) (the "TOC save slot").
    52  	//
    53  	// 2) We reserve space for a pointer in the .plt section (once
    54  	//    per referenced dynamic function).  .plt is a data
    55  	//    section filled solely by the dynamic linker (more like
    56  	//    .plt.got on other architectures).  Initially, the
    57  	//    dynamic linker will fill each slot with a pointer to the
    58  	//    corresponding x@plt entry point.
    59  	//
    60  	// 3) We generate the "call stub" x_stub (once per dynamic
    61  	//    function/object file pair).  This saves the TOC in the
    62  	//    TOC save slot, reads the function pointer from x's .plt
    63  	//    slot and calls it like any other global entry point
    64  	//    (including setting r12 to the function address).
    65  	//
    66  	// 4) We generate the "symbol resolver stub" x@plt (once per
    67  	//    dynamic function).  This is solely a branch to the glink
    68  	//    resolver stub.
    69  	//
    70  	// 5) We generate the glink resolver stub (only once).  This
    71  	//    computes which symbol resolver stub we came through and
    72  	//    invokes the dynamic resolver via a pointer provided by
    73  	//    the dynamic linker. This will patch up the .plt slot to
    74  	//    point directly at the function so future calls go
    75  	//    straight from the call stub to the real function, and
    76  	//    then call the function.
    77  
    78  	// NOTE: It's possible we could make ppc64 closer to other
    79  	// architectures: ppc64's .plt is like .plt.got on other
    80  	// platforms and ppc64's .glink is like .plt on other
    81  	// platforms.
    82  
    83  	// Find all R_PPC64_REL24 relocations that reference dynamic
    84  	// imports. Reserve PLT entries for these symbols and
    85  	// generate call stubs. The call stubs need to live in .text,
    86  	// which is why we need to do this pass this early.
    87  	//
    88  	// This assumes "case 1" from the ABI, where the caller needs
    89  	// us to save and restore the TOC pointer.
    90  	var stubs []*ld.Symbol
    91  	for _, s := range ctxt.Textp {
    92  		for i := range s.R {
    93  			r := &s.R[i]
    94  			if r.Type != 256+ld.R_PPC64_REL24 || r.Sym.Type != ld.SDYNIMPORT {
    95  				continue
    96  			}
    97  
    98  			// Reserve PLT entry and generate symbol
    99  			// resolver
   100  			addpltsym(ctxt, r.Sym)
   101  
   102  			// Generate call stub
   103  			n := fmt.Sprintf("%s.%s", s.Name, r.Sym.Name)
   104  
   105  			stub := ctxt.Syms.Lookup(n, 0)
   106  			if s.Attr.Reachable() {
   107  				stub.Attr |= ld.AttrReachable
   108  			}
   109  			if stub.Size == 0 {
   110  				// Need outer to resolve .TOC.
   111  				stub.Outer = s
   112  				stubs = append(stubs, stub)
   113  				gencallstub(ctxt, 1, stub, r.Sym)
   114  			}
   115  
   116  			// Update the relocation to use the call stub
   117  			r.Sym = stub
   118  
   119  			// Restore TOC after bl. The compiler put a
   120  			// nop here for us to overwrite.
   121  			const o1 = 0xe8410018 // ld r2,24(r1)
   122  			ctxt.Arch.ByteOrder.PutUint32(s.P[r.Off+4:], o1)
   123  		}
   124  	}
   125  	// Put call stubs at the beginning (instead of the end).
   126  	// So when resolving the relocations to calls to the stubs,
   127  	// the addresses are known and trampolines can be inserted
   128  	// when necessary.
   129  	ctxt.Textp = append(stubs, ctxt.Textp...)
   130  }
   131  
   132  func genaddmoduledata(ctxt *ld.Link) {
   133  	addmoduledata := ctxt.Syms.ROLookup("runtime.addmoduledata", 0)
   134  	if addmoduledata.Type == ld.STEXT {
   135  		return
   136  	}
   137  	addmoduledata.Attr |= ld.AttrReachable
   138  	initfunc := ctxt.Syms.Lookup("go.link.addmoduledata", 0)
   139  	initfunc.Type = ld.STEXT
   140  	initfunc.Attr |= ld.AttrLocal
   141  	initfunc.Attr |= ld.AttrReachable
   142  	o := func(op uint32) {
   143  		ld.Adduint32(ctxt, initfunc, op)
   144  	}
   145  	// addis r2, r12, .TOC.-func@ha
   146  	rel := ld.Addrel(initfunc)
   147  	rel.Off = int32(initfunc.Size)
   148  	rel.Siz = 8
   149  	rel.Sym = ctxt.Syms.Lookup(".TOC.", 0)
   150  	rel.Type = objabi.R_ADDRPOWER_PCREL
   151  	o(0x3c4c0000)
   152  	// addi r2, r2, .TOC.-func@l
   153  	o(0x38420000)
   154  	// mflr r31
   155  	o(0x7c0802a6)
   156  	// stdu r31, -32(r1)
   157  	o(0xf801ffe1)
   158  	// addis r3, r2, local.moduledata@got@ha
   159  	rel = ld.Addrel(initfunc)
   160  	rel.Off = int32(initfunc.Size)
   161  	rel.Siz = 8
   162  	rel.Sym = ctxt.Syms.Lookup("local.moduledata", 0)
   163  	rel.Type = objabi.R_ADDRPOWER_GOT
   164  	o(0x3c620000)
   165  	// ld r3, local.moduledata@got@l(r3)
   166  	o(0xe8630000)
   167  	// bl runtime.addmoduledata
   168  	rel = ld.Addrel(initfunc)
   169  	rel.Off = int32(initfunc.Size)
   170  	rel.Siz = 4
   171  	rel.Sym = addmoduledata
   172  	rel.Type = objabi.R_CALLPOWER
   173  	o(0x48000001)
   174  	// nop
   175  	o(0x60000000)
   176  	// ld r31, 0(r1)
   177  	o(0xe8010000)
   178  	// mtlr r31
   179  	o(0x7c0803a6)
   180  	// addi r1,r1,32
   181  	o(0x38210020)
   182  	// blr
   183  	o(0x4e800020)
   184  
   185  	initarray_entry := ctxt.Syms.Lookup("go.link.addmoduledatainit", 0)
   186  	ctxt.Textp = append(ctxt.Textp, initfunc)
   187  	initarray_entry.Attr |= ld.AttrReachable
   188  	initarray_entry.Attr |= ld.AttrLocal
   189  	initarray_entry.Type = ld.SINITARR
   190  	ld.Addaddr(ctxt, initarray_entry, initfunc)
   191  }
   192  
   193  func gentext(ctxt *ld.Link) {
   194  	if ctxt.DynlinkingGo() {
   195  		genaddmoduledata(ctxt)
   196  	}
   197  
   198  	if ld.Linkmode == ld.LinkInternal {
   199  		genplt(ctxt)
   200  	}
   201  }
   202  
   203  // Construct a call stub in stub that calls symbol targ via its PLT
   204  // entry.
   205  func gencallstub(ctxt *ld.Link, abicase int, stub *ld.Symbol, targ *ld.Symbol) {
   206  	if abicase != 1 {
   207  		// If we see R_PPC64_TOCSAVE or R_PPC64_REL24_NOTOC
   208  		// relocations, we'll need to implement cases 2 and 3.
   209  		log.Fatalf("gencallstub only implements case 1 calls")
   210  	}
   211  
   212  	plt := ctxt.Syms.Lookup(".plt", 0)
   213  
   214  	stub.Type = ld.STEXT
   215  
   216  	// Save TOC pointer in TOC save slot
   217  	ld.Adduint32(ctxt, stub, 0xf8410018) // std r2,24(r1)
   218  
   219  	// Load the function pointer from the PLT.
   220  	r := ld.Addrel(stub)
   221  
   222  	r.Off = int32(stub.Size)
   223  	r.Sym = plt
   224  	r.Add = int64(targ.Plt)
   225  	r.Siz = 2
   226  	if ctxt.Arch.ByteOrder == binary.BigEndian {
   227  		r.Off += int32(r.Siz)
   228  	}
   229  	r.Type = objabi.R_POWER_TOC
   230  	r.Variant = ld.RV_POWER_HA
   231  	ld.Adduint32(ctxt, stub, 0x3d820000) // addis r12,r2,targ@plt@toc@ha
   232  	r = ld.Addrel(stub)
   233  	r.Off = int32(stub.Size)
   234  	r.Sym = plt
   235  	r.Add = int64(targ.Plt)
   236  	r.Siz = 2
   237  	if ctxt.Arch.ByteOrder == binary.BigEndian {
   238  		r.Off += int32(r.Siz)
   239  	}
   240  	r.Type = objabi.R_POWER_TOC
   241  	r.Variant = ld.RV_POWER_LO
   242  	ld.Adduint32(ctxt, stub, 0xe98c0000) // ld r12,targ@plt@toc@l(r12)
   243  
   244  	// Jump to the loaded pointer
   245  	ld.Adduint32(ctxt, stub, 0x7d8903a6) // mtctr r12
   246  	ld.Adduint32(ctxt, stub, 0x4e800420) // bctr
   247  }
   248  
   249  func adddynrel(ctxt *ld.Link, s *ld.Symbol, r *ld.Reloc) bool {
   250  	targ := r.Sym
   251  
   252  	switch r.Type {
   253  	default:
   254  		if r.Type >= 256 {
   255  			ld.Errorf(s, "unexpected relocation type %d", r.Type)
   256  			return false
   257  		}
   258  
   259  		// Handle relocations found in ELF object files.
   260  	case 256 + ld.R_PPC64_REL24:
   261  		r.Type = objabi.R_CALLPOWER
   262  
   263  		// This is a local call, so the caller isn't setting
   264  		// up r12 and r2 is the same for the caller and
   265  		// callee. Hence, we need to go to the local entry
   266  		// point.  (If we don't do this, the callee will try
   267  		// to use r12 to compute r2.)
   268  		r.Add += int64(r.Sym.Localentry) * 4
   269  
   270  		if targ.Type == ld.SDYNIMPORT {
   271  			// Should have been handled in elfsetupplt
   272  			ld.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
   273  		}
   274  
   275  		return true
   276  
   277  	case 256 + ld.R_PPC_REL32:
   278  		r.Type = objabi.R_PCREL
   279  		r.Add += 4
   280  
   281  		if targ.Type == ld.SDYNIMPORT {
   282  			ld.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
   283  		}
   284  
   285  		return true
   286  
   287  	case 256 + ld.R_PPC64_ADDR64:
   288  		r.Type = objabi.R_ADDR
   289  		if targ.Type == ld.SDYNIMPORT {
   290  			// These happen in .toc sections
   291  			ld.Adddynsym(ctxt, targ)
   292  
   293  			rela := ctxt.Syms.Lookup(".rela", 0)
   294  			ld.Addaddrplus(ctxt, rela, s, int64(r.Off))
   295  			ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(targ.Dynid), ld.R_PPC64_ADDR64))
   296  			ld.Adduint64(ctxt, rela, uint64(r.Add))
   297  			r.Type = 256 // ignore during relocsym
   298  		}
   299  
   300  		return true
   301  
   302  	case 256 + ld.R_PPC64_TOC16:
   303  		r.Type = objabi.R_POWER_TOC
   304  		r.Variant = ld.RV_POWER_LO | ld.RV_CHECK_OVERFLOW
   305  		return true
   306  
   307  	case 256 + ld.R_PPC64_TOC16_LO:
   308  		r.Type = objabi.R_POWER_TOC
   309  		r.Variant = ld.RV_POWER_LO
   310  		return true
   311  
   312  	case 256 + ld.R_PPC64_TOC16_HA:
   313  		r.Type = objabi.R_POWER_TOC
   314  		r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
   315  		return true
   316  
   317  	case 256 + ld.R_PPC64_TOC16_HI:
   318  		r.Type = objabi.R_POWER_TOC
   319  		r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
   320  		return true
   321  
   322  	case 256 + ld.R_PPC64_TOC16_DS:
   323  		r.Type = objabi.R_POWER_TOC
   324  		r.Variant = ld.RV_POWER_DS | ld.RV_CHECK_OVERFLOW
   325  		return true
   326  
   327  	case 256 + ld.R_PPC64_TOC16_LO_DS:
   328  		r.Type = objabi.R_POWER_TOC
   329  		r.Variant = ld.RV_POWER_DS
   330  		return true
   331  
   332  	case 256 + ld.R_PPC64_REL16_LO:
   333  		r.Type = objabi.R_PCREL
   334  		r.Variant = ld.RV_POWER_LO
   335  		r.Add += 2 // Compensate for relocation size of 2
   336  		return true
   337  
   338  	case 256 + ld.R_PPC64_REL16_HI:
   339  		r.Type = objabi.R_PCREL
   340  		r.Variant = ld.RV_POWER_HI | ld.RV_CHECK_OVERFLOW
   341  		r.Add += 2
   342  		return true
   343  
   344  	case 256 + ld.R_PPC64_REL16_HA:
   345  		r.Type = objabi.R_PCREL
   346  		r.Variant = ld.RV_POWER_HA | ld.RV_CHECK_OVERFLOW
   347  		r.Add += 2
   348  		return true
   349  	}
   350  
   351  	// Handle references to ELF symbols from our own object files.
   352  	if targ.Type != ld.SDYNIMPORT {
   353  		return true
   354  	}
   355  
   356  	// TODO(austin): Translate our relocations to ELF
   357  
   358  	return false
   359  }
   360  
   361  func elfreloc1(ctxt *ld.Link, r *ld.Reloc, sectoff int64) int {
   362  	ld.Thearch.Vput(uint64(sectoff))
   363  
   364  	elfsym := r.Xsym.ElfsymForReloc()
   365  	switch r.Type {
   366  	default:
   367  		return -1
   368  
   369  	case objabi.R_ADDR:
   370  		switch r.Siz {
   371  		case 4:
   372  			ld.Thearch.Vput(ld.R_PPC64_ADDR32 | uint64(elfsym)<<32)
   373  		case 8:
   374  			ld.Thearch.Vput(ld.R_PPC64_ADDR64 | uint64(elfsym)<<32)
   375  		default:
   376  			return -1
   377  		}
   378  
   379  	case objabi.R_POWER_TLS:
   380  		ld.Thearch.Vput(ld.R_PPC64_TLS | uint64(elfsym)<<32)
   381  
   382  	case objabi.R_POWER_TLS_LE:
   383  		ld.Thearch.Vput(ld.R_PPC64_TPREL16 | uint64(elfsym)<<32)
   384  
   385  	case objabi.R_POWER_TLS_IE:
   386  		ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_HA | uint64(elfsym)<<32)
   387  		ld.Thearch.Vput(uint64(r.Xadd))
   388  		ld.Thearch.Vput(uint64(sectoff + 4))
   389  		ld.Thearch.Vput(ld.R_PPC64_GOT_TPREL16_LO_DS | uint64(elfsym)<<32)
   390  
   391  	case objabi.R_ADDRPOWER:
   392  		ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
   393  		ld.Thearch.Vput(uint64(r.Xadd))
   394  		ld.Thearch.Vput(uint64(sectoff + 4))
   395  		ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO | uint64(elfsym)<<32)
   396  
   397  	case objabi.R_ADDRPOWER_DS:
   398  		ld.Thearch.Vput(ld.R_PPC64_ADDR16_HA | uint64(elfsym)<<32)
   399  		ld.Thearch.Vput(uint64(r.Xadd))
   400  		ld.Thearch.Vput(uint64(sectoff + 4))
   401  		ld.Thearch.Vput(ld.R_PPC64_ADDR16_LO_DS | uint64(elfsym)<<32)
   402  
   403  	case objabi.R_ADDRPOWER_GOT:
   404  		ld.Thearch.Vput(ld.R_PPC64_GOT16_HA | uint64(elfsym)<<32)
   405  		ld.Thearch.Vput(uint64(r.Xadd))
   406  		ld.Thearch.Vput(uint64(sectoff + 4))
   407  		ld.Thearch.Vput(ld.R_PPC64_GOT16_LO_DS | uint64(elfsym)<<32)
   408  
   409  	case objabi.R_ADDRPOWER_PCREL:
   410  		ld.Thearch.Vput(ld.R_PPC64_REL16_HA | uint64(elfsym)<<32)
   411  		ld.Thearch.Vput(uint64(r.Xadd))
   412  		ld.Thearch.Vput(uint64(sectoff + 4))
   413  		ld.Thearch.Vput(ld.R_PPC64_REL16_LO | uint64(elfsym)<<32)
   414  		r.Xadd += 4
   415  
   416  	case objabi.R_ADDRPOWER_TOCREL:
   417  		ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
   418  		ld.Thearch.Vput(uint64(r.Xadd))
   419  		ld.Thearch.Vput(uint64(sectoff + 4))
   420  		ld.Thearch.Vput(ld.R_PPC64_TOC16_LO | uint64(elfsym)<<32)
   421  
   422  	case objabi.R_ADDRPOWER_TOCREL_DS:
   423  		ld.Thearch.Vput(ld.R_PPC64_TOC16_HA | uint64(elfsym)<<32)
   424  		ld.Thearch.Vput(uint64(r.Xadd))
   425  		ld.Thearch.Vput(uint64(sectoff + 4))
   426  		ld.Thearch.Vput(ld.R_PPC64_TOC16_LO_DS | uint64(elfsym)<<32)
   427  
   428  	case objabi.R_CALLPOWER:
   429  		if r.Siz != 4 {
   430  			return -1
   431  		}
   432  		ld.Thearch.Vput(ld.R_PPC64_REL24 | uint64(elfsym)<<32)
   433  
   434  	}
   435  	ld.Thearch.Vput(uint64(r.Xadd))
   436  
   437  	return 0
   438  }
   439  
   440  func elfsetupplt(ctxt *ld.Link) {
   441  	plt := ctxt.Syms.Lookup(".plt", 0)
   442  	if plt.Size == 0 {
   443  		// The dynamic linker stores the address of the
   444  		// dynamic resolver and the DSO identifier in the two
   445  		// doublewords at the beginning of the .plt section
   446  		// before the PLT array. Reserve space for these.
   447  		plt.Size = 16
   448  	}
   449  }
   450  
   451  func machoreloc1(s *ld.Symbol, r *ld.Reloc, sectoff int64) int {
   452  	return -1
   453  }
   454  
   455  // Return the value of .TOC. for symbol s
   456  func symtoc(ctxt *ld.Link, s *ld.Symbol) int64 {
   457  	var toc *ld.Symbol
   458  
   459  	if s.Outer != nil {
   460  		toc = ctxt.Syms.ROLookup(".TOC.", int(s.Outer.Version))
   461  	} else {
   462  		toc = ctxt.Syms.ROLookup(".TOC.", int(s.Version))
   463  	}
   464  
   465  	if toc == nil {
   466  		ld.Errorf(s, "TOC-relative relocation in object without .TOC.")
   467  		return 0
   468  	}
   469  
   470  	return toc.Value
   471  }
   472  
   473  func archrelocaddr(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
   474  	var o1, o2 uint32
   475  	if ctxt.Arch.ByteOrder == binary.BigEndian {
   476  		o1 = uint32(*val >> 32)
   477  		o2 = uint32(*val)
   478  	} else {
   479  		o1 = uint32(*val)
   480  		o2 = uint32(*val >> 32)
   481  	}
   482  
   483  	// We are spreading a 31-bit address across two instructions, putting the
   484  	// high (adjusted) part in the low 16 bits of the first instruction and the
   485  	// low part in the low 16 bits of the second instruction, or, in the DS case,
   486  	// bits 15-2 (inclusive) of the address into bits 15-2 of the second
   487  	// instruction (it is an error in this case if the low 2 bits of the address
   488  	// are non-zero).
   489  
   490  	t := ld.Symaddr(r.Sym) + r.Add
   491  	if t < 0 || t >= 1<<31 {
   492  		ld.Errorf(s, "relocation for %s is too big (>=2G): %d", s.Name, ld.Symaddr(r.Sym))
   493  	}
   494  	if t&0x8000 != 0 {
   495  		t += 0x10000
   496  	}
   497  
   498  	switch r.Type {
   499  	case objabi.R_ADDRPOWER:
   500  		o1 |= (uint32(t) >> 16) & 0xffff
   501  		o2 |= uint32(t) & 0xffff
   502  
   503  	case objabi.R_ADDRPOWER_DS:
   504  		o1 |= (uint32(t) >> 16) & 0xffff
   505  		if t&3 != 0 {
   506  			ld.Errorf(s, "bad DS reloc for %s: %d", s.Name, ld.Symaddr(r.Sym))
   507  		}
   508  		o2 |= uint32(t) & 0xfffc
   509  
   510  	default:
   511  		return -1
   512  	}
   513  
   514  	if ctxt.Arch.ByteOrder == binary.BigEndian {
   515  		*val = int64(o1)<<32 | int64(o2)
   516  	} else {
   517  		*val = int64(o2)<<32 | int64(o1)
   518  	}
   519  	return 0
   520  }
   521  
   522  // resolve direct jump relocation r in s, and add trampoline if necessary
   523  func trampoline(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol) {
   524  
   525  	t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
   526  	switch r.Type {
   527  	case objabi.R_CALLPOWER:
   528  
   529  		// If branch offset is too far then create a trampoline.
   530  
   531  		if int64(int32(t<<6)>>6) != t || (*ld.FlagDebugTramp > 1 && s.File != r.Sym.File) {
   532  			var tramp *ld.Symbol
   533  			for i := 0; ; i++ {
   534  
   535  				// Using r.Add as part of the name is significant in functions like duffzero where the call
   536  				// target is at some offset within the function.  Calls to duff+8 and duff+256 must appear as
   537  				// distinct trampolines.
   538  
   539  				name := r.Sym.Name
   540  				if r.Add == 0 {
   541  					name = name + fmt.Sprintf("-tramp%d", i)
   542  				} else {
   543  					name = name + fmt.Sprintf("%+x-tramp%d", r.Add, i)
   544  				}
   545  
   546  				// Look up the trampoline in case it already exists
   547  
   548  				tramp = ctxt.Syms.Lookup(name, int(r.Sym.Version))
   549  				if tramp.Value == 0 {
   550  					break
   551  				}
   552  
   553  				t = ld.Symaddr(tramp) + r.Add - (s.Value + int64(r.Off))
   554  
   555  				// If the offset of the trampoline that has been found is within range, use it.
   556  				if int64(int32(t<<6)>>6) == t {
   557  					break
   558  				}
   559  			}
   560  			if tramp.Type == 0 {
   561  				ctxt.AddTramp(tramp)
   562  				tramp.Size = 16 // 4 instructions
   563  				tramp.P = make([]byte, tramp.Size)
   564  				t = ld.Symaddr(r.Sym) + r.Add
   565  				f := t & 0xffff0000
   566  				o1 := uint32(0x3fe00000 | (f >> 16)) // lis r31,trampaddr hi (r31 is temp reg)
   567  				f = t & 0xffff
   568  				o2 := uint32(0x63ff0000 | f) // ori r31,trampaddr lo
   569  				o3 := uint32(0x7fe903a6)     // mtctr
   570  				o4 := uint32(0x4e800420)     // bctr
   571  				ld.SysArch.ByteOrder.PutUint32(tramp.P, o1)
   572  				ld.SysArch.ByteOrder.PutUint32(tramp.P[4:], o2)
   573  				ld.SysArch.ByteOrder.PutUint32(tramp.P[8:], o3)
   574  				ld.SysArch.ByteOrder.PutUint32(tramp.P[12:], o4)
   575  			}
   576  			r.Sym = tramp
   577  			r.Add = 0 // This was folded into the trampoline target address
   578  			r.Done = 0
   579  		}
   580  	default:
   581  		ld.Errorf(s, "trampoline called with non-jump reloc: %v", r.Type)
   582  	}
   583  }
   584  
   585  func archreloc(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, val *int64) int {
   586  	if ld.Linkmode == ld.LinkExternal {
   587  		switch r.Type {
   588  		default:
   589  			return -1
   590  
   591  		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
   592  			r.Done = 0
   593  			// check Outer is nil, Type is TLSBSS?
   594  			r.Xadd = r.Add
   595  			r.Xsym = r.Sym
   596  			return 0
   597  
   598  		case objabi.R_ADDRPOWER,
   599  			objabi.R_ADDRPOWER_DS,
   600  			objabi.R_ADDRPOWER_TOCREL,
   601  			objabi.R_ADDRPOWER_TOCREL_DS,
   602  			objabi.R_ADDRPOWER_GOT,
   603  			objabi.R_ADDRPOWER_PCREL:
   604  			r.Done = 0
   605  
   606  			// set up addend for eventual relocation via outer symbol.
   607  			rs := r.Sym
   608  			r.Xadd = r.Add
   609  			for rs.Outer != nil {
   610  				r.Xadd += ld.Symaddr(rs) - ld.Symaddr(rs.Outer)
   611  				rs = rs.Outer
   612  			}
   613  
   614  			if rs.Type != ld.SHOSTOBJ && rs.Type != ld.SDYNIMPORT && rs.Sect == nil {
   615  				ld.Errorf(s, "missing section for %s", rs.Name)
   616  			}
   617  			r.Xsym = rs
   618  
   619  			return 0
   620  
   621  		case objabi.R_CALLPOWER:
   622  			r.Done = 0
   623  			r.Xsym = r.Sym
   624  			r.Xadd = r.Add
   625  			return 0
   626  		}
   627  	}
   628  
   629  	switch r.Type {
   630  	case objabi.R_CONST:
   631  		*val = r.Add
   632  		return 0
   633  
   634  	case objabi.R_GOTOFF:
   635  		*val = ld.Symaddr(r.Sym) + r.Add - ld.Symaddr(ctxt.Syms.Lookup(".got", 0))
   636  		return 0
   637  
   638  	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS:
   639  		return archrelocaddr(ctxt, r, s, val)
   640  
   641  	case objabi.R_CALLPOWER:
   642  		// Bits 6 through 29 = (S + A - P) >> 2
   643  
   644  		t := ld.Symaddr(r.Sym) + r.Add - (s.Value + int64(r.Off))
   645  
   646  		if t&3 != 0 {
   647  			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
   648  		}
   649  		// If branch offset is too far then create a trampoline.
   650  
   651  		if int64(int32(t<<6)>>6) != t {
   652  			ld.Errorf(s, "direct call too far: %s %x", r.Sym.Name, t)
   653  		}
   654  		*val |= int64(uint32(t) &^ 0xfc000003)
   655  		return 0
   656  
   657  	case objabi.R_POWER_TOC: // S + A - .TOC.
   658  		*val = ld.Symaddr(r.Sym) + r.Add - symtoc(ctxt, s)
   659  
   660  		return 0
   661  
   662  	case objabi.R_POWER_TLS_LE:
   663  		// The thread pointer points 0x7000 bytes after the start of the the
   664  		// thread local storage area as documented in section "3.7.2 TLS
   665  		// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
   666  		// Specification".
   667  		v := r.Sym.Value - 0x7000
   668  		if int64(int16(v)) != v {
   669  			ld.Errorf(s, "TLS offset out of range %d", v)
   670  		}
   671  		*val = (*val &^ 0xffff) | (v & 0xffff)
   672  		return 0
   673  	}
   674  
   675  	return -1
   676  }
   677  
   678  func archrelocvariant(ctxt *ld.Link, r *ld.Reloc, s *ld.Symbol, t int64) int64 {
   679  	switch r.Variant & ld.RV_TYPE_MASK {
   680  	default:
   681  		ld.Errorf(s, "unexpected relocation variant %d", r.Variant)
   682  		fallthrough
   683  
   684  	case ld.RV_NONE:
   685  		return t
   686  
   687  	case ld.RV_POWER_LO:
   688  		if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
   689  			// Whether to check for signed or unsigned
   690  			// overflow depends on the instruction
   691  			var o1 uint32
   692  			if ctxt.Arch.ByteOrder == binary.BigEndian {
   693  				o1 = ld.Be32(s.P[r.Off-2:])
   694  			} else {
   695  				o1 = ld.Le32(s.P[r.Off:])
   696  			}
   697  			switch o1 >> 26 {
   698  			case 24, // ori
   699  				26, // xori
   700  				28: // andi
   701  				if t>>16 != 0 {
   702  					goto overflow
   703  				}
   704  
   705  			default:
   706  				if int64(int16(t)) != t {
   707  					goto overflow
   708  				}
   709  			}
   710  		}
   711  
   712  		return int64(int16(t))
   713  
   714  	case ld.RV_POWER_HA:
   715  		t += 0x8000
   716  		fallthrough
   717  
   718  		// Fallthrough
   719  	case ld.RV_POWER_HI:
   720  		t >>= 16
   721  
   722  		if r.Variant&ld.RV_CHECK_OVERFLOW != 0 {
   723  			// Whether to check for signed or unsigned
   724  			// overflow depends on the instruction
   725  			var o1 uint32
   726  			if ctxt.Arch.ByteOrder == binary.BigEndian {
   727  				o1 = ld.Be32(s.P[r.Off-2:])
   728  			} else {
   729  				o1 = ld.Le32(s.P[r.Off:])
   730  			}
   731  			switch o1 >> 26 {
   732  			case 25, // oris
   733  				27, // xoris
   734  				29: // andis
   735  				if t>>16 != 0 {
   736  					goto overflow
   737  				}
   738  
   739  			default:
   740  				if int64(int16(t)) != t {
   741  					goto overflow
   742  				}
   743  			}
   744  		}
   745  
   746  		return int64(int16(t))
   747  
   748  	case ld.RV_POWER_DS:
   749  		var o1 uint32
   750  		if ctxt.Arch.ByteOrder == binary.BigEndian {
   751  			o1 = uint32(ld.Be16(s.P[r.Off:]))
   752  		} else {
   753  			o1 = uint32(ld.Le16(s.P[r.Off:]))
   754  		}
   755  		if t&3 != 0 {
   756  			ld.Errorf(s, "relocation for %s+%d is not aligned: %d", r.Sym.Name, r.Off, t)
   757  		}
   758  		if (r.Variant&ld.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
   759  			goto overflow
   760  		}
   761  		return int64(o1)&0x3 | int64(int16(t))
   762  	}
   763  
   764  overflow:
   765  	ld.Errorf(s, "relocation for %s+%d is too big: %d", r.Sym.Name, r.Off, t)
   766  	return t
   767  }
   768  
   769  func addpltsym(ctxt *ld.Link, s *ld.Symbol) {
   770  	if s.Plt >= 0 {
   771  		return
   772  	}
   773  
   774  	ld.Adddynsym(ctxt, s)
   775  
   776  	if ld.Iself {
   777  		plt := ctxt.Syms.Lookup(".plt", 0)
   778  		rela := ctxt.Syms.Lookup(".rela.plt", 0)
   779  		if plt.Size == 0 {
   780  			elfsetupplt(ctxt)
   781  		}
   782  
   783  		// Create the glink resolver if necessary
   784  		glink := ensureglinkresolver(ctxt)
   785  
   786  		// Write symbol resolver stub (just a branch to the
   787  		// glink resolver stub)
   788  		r := ld.Addrel(glink)
   789  
   790  		r.Sym = glink
   791  		r.Off = int32(glink.Size)
   792  		r.Siz = 4
   793  		r.Type = objabi.R_CALLPOWER
   794  		ld.Adduint32(ctxt, glink, 0x48000000) // b .glink
   795  
   796  		// In the ppc64 ABI, the dynamic linker is responsible
   797  		// for writing the entire PLT.  We just need to
   798  		// reserve 8 bytes for each PLT entry and generate a
   799  		// JMP_SLOT dynamic relocation for it.
   800  		//
   801  		// TODO(austin): ABI v1 is different
   802  		s.Plt = int32(plt.Size)
   803  
   804  		plt.Size += 8
   805  
   806  		ld.Addaddrplus(ctxt, rela, plt, int64(s.Plt))
   807  		ld.Adduint64(ctxt, rela, ld.ELF64_R_INFO(uint32(s.Dynid), ld.R_PPC64_JMP_SLOT))
   808  		ld.Adduint64(ctxt, rela, 0)
   809  	} else {
   810  		ld.Errorf(s, "addpltsym: unsupported binary format")
   811  	}
   812  }
   813  
   814  // Generate the glink resolver stub if necessary and return the .glink section
   815  func ensureglinkresolver(ctxt *ld.Link) *ld.Symbol {
   816  	glink := ctxt.Syms.Lookup(".glink", 0)
   817  	if glink.Size != 0 {
   818  		return glink
   819  	}
   820  
   821  	// This is essentially the resolver from the ppc64 ELF ABI.
   822  	// At entry, r12 holds the address of the symbol resolver stub
   823  	// for the target routine and the argument registers hold the
   824  	// arguments for the target routine.
   825  	//
   826  	// This stub is PIC, so first get the PC of label 1 into r11.
   827  	// Other things will be relative to this.
   828  	ld.Adduint32(ctxt, glink, 0x7c0802a6) // mflr r0
   829  	ld.Adduint32(ctxt, glink, 0x429f0005) // bcl 20,31,1f
   830  	ld.Adduint32(ctxt, glink, 0x7d6802a6) // 1: mflr r11
   831  	ld.Adduint32(ctxt, glink, 0x7c0803a6) // mtlf r0
   832  
   833  	// Compute the .plt array index from the entry point address.
   834  	// Because this is PIC, everything is relative to label 1b (in
   835  	// r11):
   836  	//   r0 = ((r12 - r11) - (res_0 - r11)) / 4 = (r12 - res_0) / 4
   837  	ld.Adduint32(ctxt, glink, 0x3800ffd0) // li r0,-(res_0-1b)=-48
   838  	ld.Adduint32(ctxt, glink, 0x7c006214) // add r0,r0,r12
   839  	ld.Adduint32(ctxt, glink, 0x7c0b0050) // sub r0,r0,r11
   840  	ld.Adduint32(ctxt, glink, 0x7800f082) // srdi r0,r0,2
   841  
   842  	// r11 = address of the first byte of the PLT
   843  	r := ld.Addrel(glink)
   844  
   845  	r.Off = int32(glink.Size)
   846  	r.Sym = ctxt.Syms.Lookup(".plt", 0)
   847  	r.Siz = 8
   848  	r.Type = objabi.R_ADDRPOWER
   849  
   850  	ld.Adduint32(ctxt, glink, 0x3d600000) // addis r11,0,.plt@ha
   851  	ld.Adduint32(ctxt, glink, 0x396b0000) // addi r11,r11,.plt@l
   852  
   853  	// Load r12 = dynamic resolver address and r11 = DSO
   854  	// identifier from the first two doublewords of the PLT.
   855  	ld.Adduint32(ctxt, glink, 0xe98b0000) // ld r12,0(r11)
   856  	ld.Adduint32(ctxt, glink, 0xe96b0008) // ld r11,8(r11)
   857  
   858  	// Jump to the dynamic resolver
   859  	ld.Adduint32(ctxt, glink, 0x7d8903a6) // mtctr r12
   860  	ld.Adduint32(ctxt, glink, 0x4e800420) // bctr
   861  
   862  	// The symbol resolvers must immediately follow.
   863  	//   res_0:
   864  
   865  	// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
   866  	// before the first symbol resolver stub.
   867  	s := ctxt.Syms.Lookup(".dynamic", 0)
   868  
   869  	ld.Elfwritedynentsymplus(ctxt, s, ld.DT_PPC64_GLINK, glink, glink.Size-32)
   870  
   871  	return glink
   872  }
   873  
   874  func asmb(ctxt *ld.Link) {
   875  	if ctxt.Debugvlog != 0 {
   876  		ctxt.Logf("%5.2f asmb\n", ld.Cputime())
   877  	}
   878  
   879  	if ld.Iself {
   880  		ld.Asmbelfsetup()
   881  	}
   882  
   883  	for _, sect := range ld.Segtext.Sections {
   884  		ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
   885  		// Handle additional text sections with Codeblk
   886  		if sect.Name == ".text" {
   887  			ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   888  		} else {
   889  			ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
   890  		}
   891  	}
   892  
   893  	if ld.Segrodata.Filelen > 0 {
   894  		if ctxt.Debugvlog != 0 {
   895  			ctxt.Logf("%5.2f rodatblk\n", ld.Cputime())
   896  		}
   897  		ld.Cseek(int64(ld.Segrodata.Fileoff))
   898  		ld.Datblk(ctxt, int64(ld.Segrodata.Vaddr), int64(ld.Segrodata.Filelen))
   899  	}
   900  	if ld.Segrelrodata.Filelen > 0 {
   901  		if ctxt.Debugvlog != 0 {
   902  			ctxt.Logf("%5.2f relrodatblk\n", ld.Cputime())
   903  		}
   904  		ld.Cseek(int64(ld.Segrelrodata.Fileoff))
   905  		ld.Datblk(ctxt, int64(ld.Segrelrodata.Vaddr), int64(ld.Segrelrodata.Filelen))
   906  	}
   907  
   908  	if ctxt.Debugvlog != 0 {
   909  		ctxt.Logf("%5.2f datblk\n", ld.Cputime())
   910  	}
   911  
   912  	ld.Cseek(int64(ld.Segdata.Fileoff))
   913  	ld.Datblk(ctxt, int64(ld.Segdata.Vaddr), int64(ld.Segdata.Filelen))
   914  
   915  	ld.Cseek(int64(ld.Segdwarf.Fileoff))
   916  	ld.Dwarfblk(ctxt, int64(ld.Segdwarf.Vaddr), int64(ld.Segdwarf.Filelen))
   917  
   918  	/* output symbol table */
   919  	ld.Symsize = 0
   920  
   921  	ld.Lcsize = 0
   922  	symo := uint32(0)
   923  	if !*ld.FlagS {
   924  		// TODO: rationalize
   925  		if ctxt.Debugvlog != 0 {
   926  			ctxt.Logf("%5.2f sym\n", ld.Cputime())
   927  		}
   928  		switch ld.Headtype {
   929  		default:
   930  			if ld.Iself {
   931  				symo = uint32(ld.Segdwarf.Fileoff + ld.Segdwarf.Filelen)
   932  				symo = uint32(ld.Rnd(int64(symo), int64(*ld.FlagRound)))
   933  			}
   934  
   935  		case objabi.Hplan9:
   936  			symo = uint32(ld.Segdata.Fileoff + ld.Segdata.Filelen)
   937  		}
   938  
   939  		ld.Cseek(int64(symo))
   940  		switch ld.Headtype {
   941  		default:
   942  			if ld.Iself {
   943  				if ctxt.Debugvlog != 0 {
   944  					ctxt.Logf("%5.2f elfsym\n", ld.Cputime())
   945  				}
   946  				ld.Asmelfsym(ctxt)
   947  				ld.Cflush()
   948  				ld.Cwrite(ld.Elfstrdat)
   949  
   950  				if ld.Linkmode == ld.LinkExternal {
   951  					ld.Elfemitreloc(ctxt)
   952  				}
   953  			}
   954  
   955  		case objabi.Hplan9:
   956  			ld.Asmplan9sym(ctxt)
   957  			ld.Cflush()
   958  
   959  			sym := ctxt.Syms.Lookup("pclntab", 0)
   960  			if sym != nil {
   961  				ld.Lcsize = int32(len(sym.P))
   962  				for i := 0; int32(i) < ld.Lcsize; i++ {
   963  					ld.Cput(sym.P[i])
   964  				}
   965  
   966  				ld.Cflush()
   967  			}
   968  		}
   969  	}
   970  
   971  	if ctxt.Debugvlog != 0 {
   972  		ctxt.Logf("%5.2f header\n", ld.Cputime())
   973  	}
   974  	ld.Cseek(0)
   975  	switch ld.Headtype {
   976  	default:
   977  	case objabi.Hplan9: /* plan 9 */
   978  		ld.Thearch.Lput(0x647)                      /* magic */
   979  		ld.Thearch.Lput(uint32(ld.Segtext.Filelen)) /* sizes */
   980  		ld.Thearch.Lput(uint32(ld.Segdata.Filelen))
   981  		ld.Thearch.Lput(uint32(ld.Segdata.Length - ld.Segdata.Filelen))
   982  		ld.Thearch.Lput(uint32(ld.Symsize))          /* nsyms */
   983  		ld.Thearch.Lput(uint32(ld.Entryvalue(ctxt))) /* va of entry */
   984  		ld.Thearch.Lput(0)
   985  		ld.Thearch.Lput(uint32(ld.Lcsize))
   986  
   987  	case objabi.Hlinux,
   988  		objabi.Hfreebsd,
   989  		objabi.Hnetbsd,
   990  		objabi.Hopenbsd,
   991  		objabi.Hnacl:
   992  		ld.Asmbelf(ctxt, int64(symo))
   993  	}
   994  
   995  	ld.Cflush()
   996  	if *ld.FlagC {
   997  		fmt.Printf("textsize=%d\n", ld.Segtext.Filelen)
   998  		fmt.Printf("datsize=%d\n", ld.Segdata.Filelen)
   999  		fmt.Printf("bsssize=%d\n", ld.Segdata.Length-ld.Segdata.Filelen)
  1000  		fmt.Printf("symsize=%d\n", ld.Symsize)
  1001  		fmt.Printf("lcsize=%d\n", ld.Lcsize)
  1002  		fmt.Printf("total=%d\n", ld.Segtext.Filelen+ld.Segdata.Length+uint64(ld.Symsize)+uint64(ld.Lcsize))
  1003  	}
  1004  }