// Inferno utils/5l/asm.c
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/5l/asm.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package ppc64

import (
	"cmd/internal/objabi"
	"cmd/internal/sys"
	"cmd/link/internal/ld"
	"cmd/link/internal/loader"
	"cmd/link/internal/sym"
	"debug/elf"
	"encoding/binary"
	"fmt"
	"internal/buildcfg"
	"log"
	"strconv"
	"strings"
)

// The build configuration supports PC-relative instructions and relocations (limited to tested targets).
var hasPCrel = buildcfg.GOPPC64 >= 10 && buildcfg.GOOS == "linux"

const (
	// For genstub, the type of stub required by the caller.
	STUB_TOC = iota
	STUB_PCREL
)

var stubStrs = []string{
	STUB_TOC:   "_callstub_toc",
	STUB_PCREL: "_callstub_pcrel",
}

const (
	OP_TOCRESTORE    = 0xe8410018 // ld r2,24(r1)
	OP_TOCSAVE       = 0xf8410018 // std r2,24(r1)
	OP_NOP           = 0x60000000 // nop
	OP_BL            = 0x48000001 // bl 0
	OP_BCTR          = 0x4e800420 // bctr
	OP_BCTRL         = 0x4e800421 // bctrl
	OP_BCL           = 0x40000001 // bcl
	OP_ADDI          = 0x38000000 // addi
	OP_ADDIS         = 0x3c000000 // addis
	OP_LD            = 0xe8000000 // ld
	OP_PLA_PFX       = 0x06100000 // pla (prefix instruction word)
	OP_PLA_SFX       = 0x38000000 // pla (suffix instruction word)
	OP_PLD_PFX_PCREL = 0x04100000 // pld (prefix instruction word, R=1)
	OP_PLD_SFX       = 0xe4000000 // pld (suffix instruction word)
	OP_MFLR          = 0x7c0802a6 // mflr
	OP_MTLR          = 0x7c0803a6 // mtlr
	OP_MFCTR         = 0x7c0902a6 // mfctr
	OP_MTCTR         = 0x7c0903a6 // mtctr

	OP_ADDIS_R12_R2  = OP_ADDIS | 12<<21 | 2<<16  // addis r12,r2,0
	OP_ADDIS_R12_R12 = OP_ADDIS | 12<<21 | 12<<16 // addis  r12,r12,0
	OP_ADDI_R12_R12  = OP_ADDI | 12<<21 | 12<<16  // addi  r12,r12,0
	OP_PLD_SFX_R12   = OP_PLD_SFX | 12<<21        // pld   r12,0 (suffix instruction word)
	OP_PLA_SFX_R12   = OP_PLA_SFX | 12<<21        // pla   r12,0 (suffix instruction word)
	OP_LIS_R12       = OP_ADDIS | 12<<21          // lis r12,0
	OP_LD_R12_R12    = OP_LD | 12<<21 | 12<<16    // ld r12,0(r12)
	OP_MTCTR_R12     = OP_MTCTR | 12<<21          // mtctr r12
	OP_MFLR_R12      = OP_MFLR | 12<<21           // mflr r12
	OP_MFLR_R0       = OP_MFLR | 0<<21            // mflr r0
	OP_MTLR_R0       = OP_MTLR | 0<<21            // mtlr r0

	// This is a special, preferred form of bcl to obtain the next
	// instruction address (NIA, aka PC+4) in LR.
	OP_BCL_NIA = OP_BCL | 20<<21 | 31<<16 | 1<<2 // bcl 20,31,$+4

	// Masks to match opcodes
	MASK_PLD_PFX  = 0xfff70000
	MASK_PLD_SFX  = 0xfc1f0000 // Also checks RA = 0 if check value is OP_PLD_SFX.
	MASK_PLD_RT   = 0x03e00000 // Extract RT from the pld suffix.
	MASK_OP_LD    = 0xfc000003
	MASK_OP_ADDIS = 0xfc000000
)

// Generate a stub to call between TOC and NOTOC functions. See genpltstub for more details about calling stubs.
// This is almost identical to genpltstub, except the location of the target symbol is known at link time.
func genstub(ctxt *ld.Link, ldr *loader.Loader, r loader.Reloc, ri int, s loader.Sym, stubType int) (ssym loader.Sym, firstUse bool) {
	addendStr := ""
	if r.Add() != 0 {
		addendStr = fmt.Sprintf("%+d", r.Add())
	}

	stubName := fmt.Sprintf("%s%s.%s", stubStrs[stubType], addendStr, ldr.SymName(r.Sym()))
	stub := ldr.CreateSymForUpdate(stubName, 0)
	firstUse = stub.Size() == 0
	if firstUse {
		switch stubType {
		// A call from a function using a TOC pointer.
		case STUB_TOC:
			stub.AddUint32(ctxt.Arch, OP_TOCSAVE) // std r2,24(r1)
			stub.AddSymRef(ctxt.Arch, r.Sym(), r.Add(), objabi.R_ADDRPOWER_TOCREL_DS, 8)
			stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_ADDIS_R12_R2) // addis r12,r2,targ@toc@ha
			stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_ADDI_R12_R12) // addi  r12,targ@toc@l(r12)

		// A call from PC relative function.
		case STUB_PCREL:
			if buildcfg.GOPPC64 >= 10 {
				// Set up address of targ in r12, PCrel
				stub.AddSymRef(ctxt.Arch, r.Sym(), r.Add(), objabi.R_ADDRPOWER_PCREL34, 8)
				stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_PLA_PFX)
				stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_PLA_SFX_R12) // pla r12, r
			} else {
				// The target may not be a P10. Generate a P8 compatible stub.
				stub.AddUint32(ctxt.Arch, OP_MFLR_R0)  // mflr r0
				stub.AddUint32(ctxt.Arch, OP_BCL_NIA)  // bcl 20,31,1f
				stub.AddUint32(ctxt.Arch, OP_MFLR_R12) // 1: mflr r12  (r12 is the address of this instruction)
				stub.AddUint32(ctxt.Arch, OP_MTLR_R0)  // mtlr r0
				stub.AddSymRef(ctxt.Arch, r.Sym(), r.Add()+8, objabi.R_ADDRPOWER_PCREL, 8)
				stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_ADDIS_R12_R12) // addis r12,(r - 1b) + 8
				stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_ADDI_R12_R12)  // addi  r12,(r - 1b) + 12
			}
		}
		// Jump to the loaded pointer
		stub.AddUint32(ctxt.Arch, OP_MTCTR_R12) // mtctr r12
		stub.AddUint32(ctxt.Arch, OP_BCTR)      // bctr
		stub.SetType(sym.STEXT)
	}

	// Update the relocation to use the call stub
	su := ldr.MakeSymbolUpdater(s)
	su.SetRelocSym(ri, stub.Sym())

	// Rewrite the TOC restore slot (a nop) if the caller uses a TOC pointer.
	switch stubType {
	case STUB_TOC:
		rewritetoinsn(&ctxt.Target, ldr, su, int64(r.Off()+4), 0xFFFFFFFF, OP_NOP, OP_TOCRESTORE)
	}

	return stub.Sym(), firstUse
}

func genpltstub(ctxt *ld.Link, ldr *loader.Loader, r loader.Reloc, ri int, s loader.Sym) (sym loader.Sym, firstUse bool) {
	// The ppc64 ABI PLT has similar concepts to other
	// architectures, but is laid out quite differently. When we
	// see a relocation to a dynamic symbol (indicating that the
	// call needs to go through the PLT), we generate up to three
	// stubs and reserve a PLT slot.
	//
	// 1) The call site is a "bl x" where genpltstub rewrites it to
	//    "bl x_stub". Depending on the properties of the caller
	//    (see ELFv2 1.5 4.2.5.3), a nop may be expected immediately
	//    after the bl. This nop is rewritten to ld r2,24(r1) to
	//    restore the toc pointer saved by x_stub.
	//
	// 2) We reserve space for a pointer in the .plt section (once
	//    per referenced dynamic function).  .plt is a data
	//    section filled solely by the dynamic linker (more like
	//    .plt.got on other architectures).  Initially, the
	//    dynamic linker will fill each slot with a pointer to the
	//    corresponding x@plt entry point.
	//
	// 3) We generate a "call stub" x_stub based on the properties
	//    of the caller.
	//
	// 4) We generate the "symbol resolver stub" x@plt (once per
	//    dynamic function).  This is solely a branch to the glink
	//    resolver stub.
	//
	// 5) We generate the glink resolver stub (only once).  This
	//    computes which symbol resolver stub we came through and
	//    invokes the dynamic resolver via a pointer provided by
	//    the dynamic linker. This will patch up the .plt slot to
	//    point directly at the function so future calls go
	//    straight from the call stub to the real function, and
	//    then call the function.

	// NOTE: It's possible we could make ppc64 closer to other
	// architectures: ppc64's .plt is like .plt.got on other
	// platforms and ppc64's .glink is like .plt on other
	// platforms.

	// Find all relocations that reference dynamic imports.
	// Reserve PLT entries for these symbols and generate call
	// stubs. The call stubs need to live in .text, which is why we
	// need to do this pass this early.

	// Reserve PLT entry and generate symbol resolver
	addpltsym(ctxt, ldr, r.Sym())

	// The stub types are described in gencallstub.
	stubType := 0
	stubTypeStr := ""

	// For now, the choice of call stub type is determined by whether
	// the caller maintains a TOC pointer in R2. A TOC pointer implies
	// we can always generate a position independent stub.
	//
	// For dynamic calls made from an external object, a caller maintains
	// a TOC pointer only when an R_PPC64_REL24 relocation is used.
	// An R_PPC64_REL24_NOTOC relocation does not use or maintain
	// a TOC pointer, and almost always implies a Power10 target.
	//
	// For dynamic calls made from a Go caller, a TOC relative stub is
	// always needed when a TOC pointer is maintained (specifically, if
	// the Go caller is PIC, and cannot use PCrel instructions).
	if (r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_REL24)) || (!ldr.AttrExternal(s) && ldr.AttrShared(s) && !hasPCrel) {
		stubTypeStr = "_tocrel"
		stubType = 1
	} else {
		stubTypeStr = "_notoc"
		stubType = 3
	}
	n := fmt.Sprintf("_pltstub%s.%s", stubTypeStr, ldr.SymName(r.Sym()))

	// When internal linking, all text symbols share the same toc pointer.
	stub := ldr.CreateSymForUpdate(n, 0)
	firstUse = stub.Size() == 0
	if firstUse {
		gencallstub(ctxt, ldr, stubType, stub, r.Sym())
	}

	// Update the relocation to use the call stub
	su := ldr.MakeSymbolUpdater(s)
	su.SetRelocSym(ri, stub.Sym())

	// A type 1 call must restore the toc pointer after the call.
	if stubType == 1 {
		su.MakeWritable()
		p := su.Data()

		// Check for a toc pointer restore slot (a nop), and rewrite to restore the toc pointer.
		var nop uint32
		if len(p) >= int(r.Off()+8) {
			nop = ctxt.Arch.ByteOrder.Uint32(p[r.Off()+4:])
		}
		if nop != OP_NOP {
			ldr.Errorf(s, "Symbol %s is missing toc restoration slot at offset %d", ldr.SymName(s), r.Off()+4)
		}
		ctxt.Arch.ByteOrder.PutUint32(p[r.Off()+4:], OP_TOCRESTORE)
	}

	return stub.Sym(), firstUse
}

// Scan relocs and generate PLT stubs and generate/fixup ABI defined functions created by the linker.
func genstubs(ctxt *ld.Link, ldr *loader.Loader) {
	var stubs []loader.Sym
	var abifuncs []loader.Sym
	for _, s := range ctxt.Textp {
		relocs := ldr.Relocs(s)
		for i := 0; i < relocs.Count(); i++ {
			r := relocs.At(i)
			switch r.Type() {
			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
				switch ldr.SymType(r.Sym()) {
				case sym.SDYNIMPORT:
					// This call goes through the PLT, generate and call through a PLT stub.
					if sym, firstUse := genpltstub(ctxt, ldr, r, i, s); firstUse {
						stubs = append(stubs, sym)
					}

				case sym.SXREF:
					// Is this an ELF ABI defined function which is (in practice)
					// generated by the linker to save/restore callee save registers?
					// These are defined similarly for both PPC64 ELF and ELFv2.
					targName := ldr.SymName(r.Sym())
					if strings.HasPrefix(targName, "_save") || strings.HasPrefix(targName, "_rest") {
						if sym, firstUse := rewriteABIFuncReloc(ctxt, ldr, targName, r); firstUse {
							abifuncs = append(abifuncs, sym)
						}
					}
				case sym.STEXT:
					targ := r.Sym()
					if (ldr.AttrExternal(targ) && ldr.SymLocalentry(targ) != 1) || !ldr.AttrExternal(targ) {
						// All local symbols share the same TOC pointer. This caller has a valid TOC
						// pointer in R2. Calls into a Go symbol preserve R2. No call stub is needed.
					} else {
						// This caller has a TOC pointer. The callee might clobber it. R2 needs to be saved
						// and restored.
						if sym, firstUse := genstub(ctxt, ldr, r, i, s, STUB_TOC); firstUse {
							stubs = append(stubs, sym)
						}
					}
				}

			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24_P9NOTOC):
				// This can be treated identically to R_PPC64_REL24_NOTOC, as stubs are determined by
				// GOPPC64 and -buildmode.
				fallthrough
			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24_NOTOC):
				switch ldr.SymType(r.Sym()) {
				case sym.SDYNIMPORT:
					// This call goes through the PLT, generate and call through a PLT stub.
					if sym, firstUse := genpltstub(ctxt, ldr, r, i, s); firstUse {
						stubs = append(stubs, sym)
					}

				case sym.SXREF:
					// TODO: This is not supported yet.
					ldr.Errorf(s, "Unsupported NOTOC external reference call into %s", ldr.SymName(r.Sym()))

				case sym.STEXT:
					targ := r.Sym()
					if (ldr.AttrExternal(targ) && ldr.SymLocalentry(targ) <= 1) || (!ldr.AttrExternal(targ) && (!ldr.AttrShared(targ) || hasPCrel)) {
						// This is NOTOC to NOTOC call (st_other is 0 or 1). No call stub is needed.
					} else {
						// This is a NOTOC to TOC function. Generate a calling stub.
						if sym, firstUse := genstub(ctxt, ldr, r, i, s, STUB_PCREL); firstUse {
							stubs = append(stubs, sym)
						}
					}
				}

			// Handle objects compiled with -fno-plt. Rewrite local calls to avoid indirect calling.
			// These are 0 sized relocs. They mark the mtctr r12, or bctrl + ld r2,24(r1).
			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLTSEQ):
				if ldr.SymType(r.Sym()) == sym.STEXT {
					// This should be an mtctr instruction. Turn it into a nop.
					su := ldr.MakeSymbolUpdater(s)
					const MASK_OP_MTCTR = 63<<26 | 0x3FF<<11 | 0x1FF<<1
					rewritetonop(&ctxt.Target, ldr, su, int64(r.Off()), MASK_OP_MTCTR, OP_MTCTR)
				}
			case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLTCALL):
				if ldr.SymType(r.Sym()) == sym.STEXT {
					// This relocation should point to a bctrl followed by a ld r2, 24(41)
					// Convert the bctrl into a bl.
					su := ldr.MakeSymbolUpdater(s)
					rewritetoinsn(&ctxt.Target, ldr, su, int64(r.Off()), 0xFFFFFFFF, OP_BCTRL, OP_BL)

					// Turn this reloc into an R_CALLPOWER, and convert the TOC restore into a nop.
					su.SetRelocType(i, objabi.R_CALLPOWER)
					localEoffset := int64(ldr.SymLocalentry(r.Sym()))
					if localEoffset == 1 {
						ldr.Errorf(s, "Unsupported NOTOC call to %s", ldr.SymName(r.Sym()))
					}
					su.SetRelocAdd(i, r.Add()+localEoffset)
					r.SetSiz(4)
					rewritetonop(&ctxt.Target, ldr, su, int64(r.Off()+4), 0xFFFFFFFF, OP_TOCRESTORE)
				}
			}
		}
	}

	// Append any usage of the go versions of ELF save/restore
	// functions to the end of the callstub list to minimize
	// chances a trampoline might be needed.
	stubs = append(stubs, abifuncs...)

	// Put stubs at the beginning (instead of the end).
	// So when resolving the relocations to calls to the stubs,
	// the addresses are known and trampolines can be inserted
	// when necessary.
	ctxt.Textp = append(stubs, ctxt.Textp...)
}

func genaddmoduledata(ctxt *ld.Link, ldr *loader.Loader) {
	initfunc, addmoduledata := ld.PrepareAddmoduledata(ctxt)
	if initfunc == nil {
		return
	}

	o := func(op uint32) {
		initfunc.AddUint32(ctxt.Arch, op)
	}

	// Write a function to load this module's local.moduledata. This is shared code.
	//
	// package link
	// void addmoduledata() {
	//	runtime.addmoduledata(local.moduledata)
	// }

	if !hasPCrel {
		// Regenerate TOC from R12 (the address of this function).
		sz := initfunc.AddSymRef(ctxt.Arch, ctxt.DotTOC[0], 0, objabi.R_ADDRPOWER_PCREL, 8)
		initfunc.SetUint32(ctxt.Arch, sz-8, 0x3c4c0000) // addis r2, r12, .TOC.-func@ha
		initfunc.SetUint32(ctxt.Arch, sz-4, 0x38420000) // addi r2, r2, .TOC.-func@l
	}

	// This is Go ABI. Stack a frame and save LR.
	o(OP_MFLR_R0) // mflr r0
	o(0xf801ffe1) // stdu r0, -32(r1)

	// Get the moduledata pointer from GOT and put into R3.
	var tgt loader.Sym
	if s := ldr.Lookup("local.moduledata", 0); s != 0 {
		tgt = s
	} else if s := ldr.Lookup("local.pluginmoduledata", 0); s != 0 {
		tgt = s
	} else {
		tgt = ldr.LookupOrCreateSym("runtime.firstmoduledata", 0)
	}

	if !hasPCrel {
		sz := initfunc.AddSymRef(ctxt.Arch, tgt, 0, objabi.R_ADDRPOWER_GOT, 8)
		initfunc.SetUint32(ctxt.Arch, sz-8, 0x3c620000) // addis r3, r2, local.moduledata@got@ha
		initfunc.SetUint32(ctxt.Arch, sz-4, 0xe8630000) // ld r3, local.moduledata@got@l(r3)
	} else {
		sz := initfunc.AddSymRef(ctxt.Arch, tgt, 0, objabi.R_ADDRPOWER_GOT_PCREL34, 8)
		// Note, this is prefixed instruction. It must not cross a 64B boundary.
		// It is doubleworld aligned here, so it will never cross (this function is 16B aligned, minimum).
		initfunc.SetUint32(ctxt.Arch, sz-8, OP_PLD_PFX_PCREL)
		initfunc.SetUint32(ctxt.Arch, sz-4, OP_PLD_SFX|(3<<21)) // pld r3, local.moduledata@got@pcrel
	}

	// Call runtime.addmoduledata
	sz := initfunc.AddSymRef(ctxt.Arch, addmoduledata, 0, objabi.R_CALLPOWER, 4)
	initfunc.SetUint32(ctxt.Arch, sz-4, OP_BL) // bl runtime.addmoduledata
	o(OP_NOP)                                  // nop (for TOC restore)

	// Pop stack frame and return.
	o(0xe8010000) // ld r0, 0(r1)
	o(OP_MTLR_R0) // mtlr r0
	o(0x38210020) // addi r1,r1,32
	o(0x4e800020) // blr
}

// Rewrite ELF (v1 or v2) calls to _savegpr0_n, _savegpr1_n, _savefpr_n, _restfpr_n, _savevr_m, or
// _restvr_m (14<=n<=31, 20<=m<=31). Redirect them to runtime.elf_restgpr0+(n-14)*4,
// runtime.elf_restvr+(m-20)*8, and similar.
//
// These functions are defined in the ELFv2 ABI (generated when using gcc -Os option) to save and
// restore callee-saved registers (as defined in the PPC64 ELF ABIs) from registers n or m to 31 of
// the named type. R12 and R0 are sometimes used in exceptional ways described in the ABI.
//
// Final note, this is only needed when linking internally. The external linker will generate these
// functions if they are used.
func rewriteABIFuncReloc(ctxt *ld.Link, ldr *loader.Loader, tname string, r loader.Reloc) (sym loader.Sym, firstUse bool) {
	s := strings.Split(tname, "_")
	// A valid call will split like {"", "savegpr0", "20"}
	if len(s) != 3 {
		return 0, false // Not an abi func.
	}
	minReg := 14 // _savegpr0_{n}, _savegpr1_{n}, _savefpr_{n}, 14 <= n <= 31
	offMul := 4  // 1 instruction per register op.
	switch s[1] {
	case "savegpr0", "savegpr1", "savefpr":
	case "restgpr0", "restgpr1", "restfpr":
	case "savevr", "restvr":
		minReg = 20 // _savevr_{n} or _restvr_{n}, 20 <= n <= 31
		offMul = 8  // 2 instructions per register op.
	default:
		return 0, false // Not an abi func
	}
	n, e := strconv.Atoi(s[2])
	if e != nil || n < minReg || n > 31 || r.Add() != 0 {
		return 0, false // Invalid register number, or non-zero addend. Not an abi func.
	}

	// tname is a valid relocation to an ABI defined register save/restore function. Re-relocate
	// them to a go version of these functions in runtime/asm_ppc64x.s
	ts := ldr.LookupOrCreateSym("runtime.elf_"+s[1], 0)
	r.SetSym(ts)
	r.SetAdd(int64((n - minReg) * offMul))
	firstUse = !ldr.AttrReachable(ts)
	if firstUse {
		ldr.SetAttrReachable(ts, true)
		// This function only becomes reachable now. It has been dropped from
		// the text section (it was unreachable until now), it needs included.
		//
		// Similarly, TOC regeneration should not happen for these functions,
		// remove it from this save/restore function.
		if ldr.AttrShared(ts) {
			sb := ldr.MakeSymbolUpdater(ts)
			sb.SetData(sb.Data()[8:])
			sb.SetSize(sb.Size() - 8)
			relocs := sb.Relocs()
			// Only one PCREL reloc to .TOC. should be present.
			if relocs.Count() != 1 {
				log.Fatalf("Unexpected number of relocs in %s\n", ldr.SymName(ts))
			}
			sb.ResetRelocs()

		}
	}
	return ts, firstUse
}

func gentext(ctxt *ld.Link, ldr *loader.Loader) {
	if ctxt.DynlinkingGo() {
		genaddmoduledata(ctxt, ldr)
	}

	if ctxt.LinkMode == ld.LinkInternal {
		genstubs(ctxt, ldr)
	}
}

// Create a calling stub. The stubType maps directly to the properties listed in the ELFv2 1.5
// section 4.2.5.3.
//
// There are 3 cases today (as paraphrased from the ELFv2 document):
//
//  1. R2 holds the TOC pointer on entry. The call stub must save R2 into the ELFv2 TOC stack save slot.
//
//  2. R2 holds the TOC pointer on entry. The caller has already saved R2 to the TOC stack save slot.
//
//  3. R2 does not hold the TOC pointer on entry. The caller has no expectations of R2.
//
// Go only needs case 1 and 3 today. Go symbols which have AttrShare set could use case 2, but case 1 always
// works in those cases too.
func gencallstub(ctxt *ld.Link, ldr *loader.Loader, stubType int, stub *loader.SymbolBuilder, targ loader.Sym) {
	plt := ctxt.PLT
	stub.SetType(sym.STEXT)

	switch stubType {
	case 1:
		// Save TOC, then load targ address from PLT using TOC.
		stub.AddUint32(ctxt.Arch, OP_TOCSAVE) // std r2,24(r1)
		stub.AddSymRef(ctxt.Arch, plt, int64(ldr.SymPlt(targ)), objabi.R_ADDRPOWER_TOCREL_DS, 8)
		stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_ADDIS_R12_R2) // addis r12,r2,targ@plt@toc@ha
		stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_LD_R12_R12)   // ld r12,targ@plt@toc@l(r12)
	case 3:
		// No TOC needs to be saved, but the stub may need to position-independent.
		if buildcfg.GOPPC64 >= 10 {
			// Power10 is supported, load targ address into r12 using PCrel load.
			stub.AddSymRef(ctxt.Arch, plt, int64(ldr.SymPlt(targ)), objabi.R_ADDRPOWER_PCREL34, 8)
			stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_PLD_PFX_PCREL)
			stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_PLD_SFX_R12) // pld r12, targ@plt
		} else if !isLinkingPIC(ctxt) {
			// This stub doesn't need to be PIC. Load targ address from the PLT via its absolute address.
			stub.AddSymRef(ctxt.Arch, plt, int64(ldr.SymPlt(targ)), objabi.R_ADDRPOWER_DS, 8)
			stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_LIS_R12)    // lis r12,targ@plt@ha
			stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_LD_R12_R12) // ld r12,targ@plt@l(r12)
		} else {
			// Generate a PIC stub. This is ugly as the stub must determine its location using
			// POWER8 or older instruction. These stubs are likely the combination of using
			// GOPPC64 < 8 and linking external objects built with CFLAGS="... -mcpu=power10 ..."
			stub.AddUint32(ctxt.Arch, OP_MFLR_R0)  // mflr r0
			stub.AddUint32(ctxt.Arch, OP_BCL_NIA)  // bcl 20,31,1f
			stub.AddUint32(ctxt.Arch, OP_MFLR_R12) // 1: mflr r12  (r12 is the address of this instruction)
			stub.AddUint32(ctxt.Arch, OP_MTLR_R0)  // mtlr r0
			stub.AddSymRef(ctxt.Arch, plt, int64(ldr.SymPlt(targ))+8, objabi.R_ADDRPOWER_PCREL, 8)
			stub.SetUint32(ctxt.Arch, stub.Size()-8, OP_ADDIS_R12_R12) // addis r12,(targ@plt - 1b) + 8
			stub.SetUint32(ctxt.Arch, stub.Size()-4, OP_ADDI_R12_R12)  // addi  r12,(targ@plt - 1b) + 12
			stub.AddUint32(ctxt.Arch, OP_LD_R12_R12)                   // ld r12, 0(r12)
		}
	default:
		log.Fatalf("gencallstub does not support ELFv2 ABI property %d", stubType)
	}

	// Jump to the loaded pointer
	stub.AddUint32(ctxt.Arch, OP_MTCTR_R12) // mtctr r12
	stub.AddUint32(ctxt.Arch, OP_BCTR)      // bctr
}

// Rewrite the instruction at offset into newinsn. Also, verify the
// existing instruction under mask matches the check value.
func rewritetoinsn(target *ld.Target, ldr *loader.Loader, su *loader.SymbolBuilder, offset int64, mask, check, newinsn uint32) {
	su.MakeWritable()
	op := target.Arch.ByteOrder.Uint32(su.Data()[offset:])
	if op&mask != check {
		ldr.Errorf(su.Sym(), "Rewrite offset 0x%x to 0x%08X failed check (0x%08X&0x%08X != 0x%08X)", offset, newinsn, op, mask, check)
	}
	su.SetUint32(target.Arch, offset, newinsn)
}

// Rewrite the instruction at offset into a hardware nop instruction. Also, verify the
// existing instruction under mask matches the check value.
func rewritetonop(target *ld.Target, ldr *loader.Loader, su *loader.SymbolBuilder, offset int64, mask, check uint32) {
	rewritetoinsn(target, ldr, su, offset, mask, check, OP_NOP)
}

func adddynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
	if target.IsElf() {
		return addelfdynrel(target, ldr, syms, s, r, rIdx)
	} else if target.IsAIX() {
		return ld.Xcoffadddynrel(target, ldr, syms, s, r, rIdx)
	}
	return false
}

func addelfdynrel(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym, r loader.Reloc, rIdx int) bool {
	targ := r.Sym()
	var targType sym.SymKind
	if targ != 0 {
		targType = ldr.SymType(targ)
	}

	switch r.Type() {
	default:
		if r.Type() >= objabi.ElfRelocOffset {
			ldr.Errorf(s, "unexpected relocation type %d (%s)", r.Type(), sym.RelocName(target.Arch, r.Type()))
			return false
		}

		// Handle relocations found in ELF object files.
	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24_NOTOC),
		objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24_P9NOTOC):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_CALLPOWER)

		if targType == sym.SDYNIMPORT {
			// Should have been handled in elfsetupplt
			ldr.Errorf(s, "unexpected R_PPC64_REL24_NOTOC/R_PPC64_REL24_P9NOTOC for dyn import")
		}
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL24):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_CALLPOWER)

		// This is a local call, so the caller isn't setting
		// up r12 and r2 is the same for the caller and
		// callee. Hence, we need to go to the local entry
		// point.  (If we don't do this, the callee will try
		// to use r12 to compute r2.)
		localEoffset := int64(ldr.SymLocalentry(targ))
		if localEoffset == 1 {
			ldr.Errorf(s, "Unsupported NOTOC call to %s", targ)
		}
		su.SetRelocAdd(rIdx, r.Add()+localEoffset)

		if targType == sym.SDYNIMPORT {
			// Should have been handled in elfsetupplt
			ldr.Errorf(s, "unexpected R_PPC64_REL24 for dyn import")
		}

		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PCREL34):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_ADDRPOWER_PCREL34)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_GOT_PCREL34):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_ADDRPOWER_PCREL34)
		if targType != sym.STEXT {
			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_PPC64_GLOB_DAT))
			su.SetRelocSym(rIdx, syms.GOT)
			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
		} else {
			// The address of targ is known at link time. Rewrite to "pla rt,targ" from "pld rt,targ@got"
			rewritetoinsn(target, ldr, su, int64(r.Off()), MASK_PLD_PFX, OP_PLD_PFX_PCREL, OP_PLA_PFX)
			pla_sfx := target.Arch.ByteOrder.Uint32(su.Data()[r.Off()+4:])&MASK_PLD_RT | OP_PLA_SFX
			rewritetoinsn(target, ldr, su, int64(r.Off()+4), MASK_PLD_SFX, OP_PLD_SFX, pla_sfx)
		}
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC_REL32):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_PCREL)
		su.SetRelocAdd(rIdx, r.Add()+4)

		if targType == sym.SDYNIMPORT {
			ldr.Errorf(s, "unexpected R_PPC_REL32 for dyn import")
		}

		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_ADDR64):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_ADDR)
		if targType == sym.SDYNIMPORT {
			// These happen in .toc sections
			ld.Adddynsym(ldr, target, syms, targ)

			rela := ldr.MakeSymbolUpdater(syms.Rela)
			rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
			rela.AddUint64(target.Arch, elf.R_INFO(uint32(ldr.SymDynid(targ)), uint32(elf.R_PPC64_ADDR64)))
			rela.AddUint64(target.Arch, uint64(r.Add()))
			su.SetRelocType(rIdx, objabi.ElfRelocOffset) // ignore during relocsym
		} else if target.IsPIE() && target.IsInternal() {
			// For internal linking PIE, this R_ADDR relocation cannot
			// be resolved statically. We need to generate a dynamic
			// relocation. Let the code below handle it.
			break
		}
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO|sym.RV_CHECK_OVERFLOW)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HA):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_HI):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HI|sym.RV_CHECK_OVERFLOW)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_DS):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS|sym.RV_CHECK_OVERFLOW)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_TOC16_LO_DS):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_LO):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_PCREL)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_LO)
		su.SetRelocAdd(rIdx, r.Add()+2) // Compensate for relocation size of 2
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HI):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_PCREL)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HI|sym.RV_CHECK_OVERFLOW)
		su.SetRelocAdd(rIdx, r.Add()+2)
		return true

	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_REL16_HA):
		su := ldr.MakeSymbolUpdater(s)
		su.SetRelocType(rIdx, objabi.R_PCREL)
		ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
		su.SetRelocAdd(rIdx, r.Add()+2)
		return true

	// When compiling with gcc's -fno-plt option (no PLT), the following code and relocation
	// sequences may be present to call an external function:
	//
	//   1. addis Rx,foo@R_PPC64_PLT16_HA
	//   2. ld 12,foo@R_PPC64_PLT16_LO_DS(Rx)
	//   3. mtctr 12 ; foo@R_PPC64_PLTSEQ
	//   4. bctrl ; foo@R_PPC64_PLTCALL
	//   5. ld r2,24(r1)
	//
	// Note, 5 is required to follow the R_PPC64_PLTCALL. Similarly, relocations targeting
	// instructions 3 and 4 are zero sized informational relocations.
	case objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLT16_HA),
		objabi.ElfRelocOffset + objabi.RelocType(elf.R_PPC64_PLT16_LO_DS):
		su := ldr.MakeSymbolUpdater(s)
		isPLT16_LO_DS := r.Type() == objabi.ElfRelocOffset+objabi.RelocType(elf.R_PPC64_PLT16_LO_DS)
		if isPLT16_LO_DS {
			ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_DS)
		} else {
			ldr.SetRelocVariant(s, rIdx, sym.RV_POWER_HA|sym.RV_CHECK_OVERFLOW)
		}
		su.SetRelocType(rIdx, objabi.R_POWER_TOC)
		if targType == sym.SDYNIMPORT {
			// This is an external symbol, make space in the GOT and retarget the reloc.
			ld.AddGotSym(target, ldr, syms, targ, uint32(elf.R_PPC64_GLOB_DAT))
			su.SetRelocSym(rIdx, syms.GOT)
			su.SetRelocAdd(rIdx, r.Add()+int64(ldr.SymGot(targ)))
		} else if targType == sym.STEXT {
			if isPLT16_LO_DS {
				// Expect an ld opcode to nop
				rewritetonop(target, ldr, su, int64(r.Off()), MASK_OP_LD, OP_LD)
			} else {
				// Expect an addis opcode to nop
				rewritetonop(target, ldr, su, int64(r.Off()), MASK_OP_ADDIS, OP_ADDIS)
			}
			// And we can ignore this reloc now.
			su.SetRelocType(rIdx, objabi.ElfRelocOffset)
		} else {
			ldr.Errorf(s, "unexpected PLT relocation target symbol type %s", targType.String())
		}
		return true
	}

	// Handle references to ELF symbols from our own object files.
	relocs := ldr.Relocs(s)
	r = relocs.At(rIdx)

	switch r.Type() {
	case objabi.R_ADDR:
		if ldr.SymType(s) == sym.STEXT {
			log.Fatalf("R_ADDR relocation in text symbol %s is unsupported\n", ldr.SymName(s))
		}
		if target.IsPIE() && target.IsInternal() {
			// When internally linking, generate dynamic relocations
			// for all typical R_ADDR relocations. The exception
			// are those R_ADDR that are created as part of generating
			// the dynamic relocations and must be resolved statically.
			//
			// There are three phases relevant to understanding this:
			//
			//	dodata()  // we are here
			//	address() // symbol address assignment
			//	reloc()   // resolution of static R_ADDR relocs
			//
			// At this point symbol addresses have not been
			// assigned yet (as the final size of the .rela section
			// will affect the addresses), and so we cannot write
			// the Elf64_Rela.r_offset now. Instead we delay it
			// until after the 'address' phase of the linker is
			// complete. We do this via Addaddrplus, which creates
			// a new R_ADDR relocation which will be resolved in
			// the 'reloc' phase.
			//
			// These synthetic static R_ADDR relocs must be skipped
			// now, or else we will be caught in an infinite loop
			// of generating synthetic relocs for our synthetic
			// relocs.
			//
			// Furthermore, the rela sections contain dynamic
			// relocations with R_ADDR relocations on
			// Elf64_Rela.r_offset. This field should contain the
			// symbol offset as determined by reloc(), not the
			// final dynamically linked address as a dynamic
			// relocation would provide.
			switch ldr.SymName(s) {
			case ".dynsym", ".rela", ".rela.plt", ".got.plt", ".dynamic":
				return false
			}
		} else {
			// Either internally linking a static executable,
			// in which case we can resolve these relocations
			// statically in the 'reloc' phase, or externally
			// linking, in which case the relocation will be
			// prepared in the 'reloc' phase and passed to the
			// external linker in the 'asmb' phase.
			if ldr.SymType(s) != sym.SDATA && ldr.SymType(s) != sym.SRODATA {
				break
			}
		}
		// Generate R_PPC64_RELATIVE relocations for best
		// efficiency in the dynamic linker.
		//
		// As noted above, symbol addresses have not been
		// assigned yet, so we can't generate the final reloc
		// entry yet. We ultimately want:
		//
		// r_offset = s + r.Off
		// r_info = R_PPC64_RELATIVE
		// r_addend = targ + r.Add
		//
		// The dynamic linker will set *offset = base address +
		// addend.
		//
		// AddAddrPlus is used for r_offset and r_addend to
		// generate new R_ADDR relocations that will update
		// these fields in the 'reloc' phase.
		rela := ldr.MakeSymbolUpdater(syms.Rela)
		rela.AddAddrPlus(target.Arch, s, int64(r.Off()))
		if r.Siz() == 8 {
			rela.AddUint64(target.Arch, elf.R_INFO(0, uint32(elf.R_PPC64_RELATIVE)))
		} else {
			ldr.Errorf(s, "unexpected relocation for dynamic symbol %s", ldr.SymName(targ))
		}
		rela.AddAddrPlus(target.Arch, targ, int64(r.Add()))

		// Not mark r done here. So we still apply it statically,
		// so in the file content we'll also have the right offset
		// to the relocation target. So it can be examined statically
		// (e.g. go version).
		return true
	}

	return false
}

func xcoffreloc1(arch *sys.Arch, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, sectoff int64) bool {
	rs := r.Xsym

	emitReloc := func(v uint16, off uint64) {
		out.Write64(uint64(sectoff) + off)
		out.Write32(uint32(ldr.SymDynid(rs)))
		out.Write16(v)
	}

	var v uint16
	switch r.Type {
	default:
		return false
	case objabi.R_ADDR, objabi.R_DWARFSECREF:
		v = ld.XCOFF_R_POS
		if r.Size == 4 {
			v |= 0x1F << 8
		} else {
			v |= 0x3F << 8
		}
		emitReloc(v, 0)
	case objabi.R_ADDRPOWER_TOCREL:
	case objabi.R_ADDRPOWER_TOCREL_DS:
		emitReloc(ld.XCOFF_R_TOCU|(0x0F<<8), 2)
		emitReloc(ld.XCOFF_R_TOCL|(0x0F<<8), 6)
	case objabi.R_POWER_TLS_LE:
		// This only supports 16b relocations.  It is fixed up in archreloc.
		emitReloc(ld.XCOFF_R_TLS_LE|0x0F<<8, 2)
	case objabi.R_CALLPOWER:
		if r.Size != 4 {
			return false
		}
		emitReloc(ld.XCOFF_R_RBR|0x19<<8, 0)
	case objabi.R_XCOFFREF:
		emitReloc(ld.XCOFF_R_REF|0x3F<<8, 0)
	}
	return true

}

func elfreloc1(ctxt *ld.Link, out *ld.OutBuf, ldr *loader.Loader, s loader.Sym, r loader.ExtReloc, ri int, sectoff int64) bool {
	// Beware that bit0~bit15 start from the third byte of an instruction in Big-Endian machines.
	rt := r.Type
	if rt == objabi.R_ADDR || rt == objabi.R_POWER_TLS || rt == objabi.R_CALLPOWER || rt == objabi.R_DWARFSECREF {
	} else {
		if ctxt.Arch.ByteOrder == binary.BigEndian {
			sectoff += 2
		}
	}
	out.Write64(uint64(sectoff))

	elfsym := ld.ElfSymForReloc(ctxt, r.Xsym)
	switch rt {
	default:
		return false
	case objabi.R_ADDR, objabi.R_DWARFSECREF:
		switch r.Size {
		case 4:
			out.Write64(uint64(elf.R_PPC64_ADDR32) | uint64(elfsym)<<32)
		case 8:
			out.Write64(uint64(elf.R_PPC64_ADDR64) | uint64(elfsym)<<32)
		default:
			return false
		}
	case objabi.R_ADDRPOWER_D34:
		out.Write64(uint64(elf.R_PPC64_D34) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_PCREL34:
		out.Write64(uint64(elf.R_PPC64_PCREL34) | uint64(elfsym)<<32)
	case objabi.R_POWER_TLS:
		out.Write64(uint64(elf.R_PPC64_TLS) | uint64(elfsym)<<32)
	case objabi.R_POWER_TLS_LE:
		out.Write64(uint64(elf.R_PPC64_TPREL16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_TPREL16_LO) | uint64(elfsym)<<32)
	case objabi.R_POWER_TLS_LE_TPREL34:
		out.Write64(uint64(elf.R_PPC64_TPREL34) | uint64(elfsym)<<32)
	case objabi.R_POWER_TLS_IE_PCREL34:
		out.Write64(uint64(elf.R_PPC64_GOT_TPREL_PCREL34) | uint64(elfsym)<<32)
	case objabi.R_POWER_TLS_IE:
		out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_GOT_TPREL16_LO_DS) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER:
		out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_ADDR16_LO) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_DS:
		out.Write64(uint64(elf.R_PPC64_ADDR16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_ADDR16_LO_DS) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_GOT:
		out.Write64(uint64(elf.R_PPC64_GOT16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_GOT16_LO_DS) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_GOT_PCREL34:
		out.Write64(uint64(elf.R_PPC64_GOT_PCREL34) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_PCREL:
		out.Write64(uint64(elf.R_PPC64_REL16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_REL16_LO) | uint64(elfsym)<<32)
		r.Xadd += 4
	case objabi.R_ADDRPOWER_TOCREL:
		out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_TOC16_LO) | uint64(elfsym)<<32)
	case objabi.R_ADDRPOWER_TOCREL_DS:
		out.Write64(uint64(elf.R_PPC64_TOC16_HA) | uint64(elfsym)<<32)
		out.Write64(uint64(r.Xadd))
		out.Write64(uint64(sectoff + 4))
		out.Write64(uint64(elf.R_PPC64_TOC16_LO_DS) | uint64(elfsym)<<32)
	case objabi.R_CALLPOWER:
		if r.Size != 4 {
			return false
		}
		if !hasPCrel {
			out.Write64(uint64(elf.R_PPC64_REL24) | uint64(elfsym)<<32)
		} else {
			// TOC is not used in PCrel compiled Go code.
			out.Write64(uint64(elf.R_PPC64_REL24_NOTOC) | uint64(elfsym)<<32)
		}

	}
	out.Write64(uint64(r.Xadd))

	return true
}

func elfsetupplt(ctxt *ld.Link, plt, got *loader.SymbolBuilder, dynamic loader.Sym) {
	if plt.Size() == 0 {
		// The dynamic linker stores the address of the
		// dynamic resolver and the DSO identifier in the two
		// doublewords at the beginning of the .plt section
		// before the PLT array. Reserve space for these.
		plt.SetSize(16)
	}
}

func machoreloc1(*sys.Arch, *ld.OutBuf, *loader.Loader, loader.Sym, loader.ExtReloc, int64) bool {
	return false
}

// Return the value of .TOC. for symbol s
func symtoc(ldr *loader.Loader, syms *ld.ArchSyms, s loader.Sym) int64 {
	v := ldr.SymVersion(s)
	if out := ldr.OuterSym(s); out != 0 {
		v = ldr.SymVersion(out)
	}

	toc := syms.DotTOC[v]
	if toc == 0 {
		ldr.Errorf(s, "TOC-relative relocation in object without .TOC.")
		return 0
	}

	return ldr.SymValue(toc)
}

// archreloctoc relocates a TOC relative symbol.
func archreloctoc(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) int64 {
	rs := r.Sym()
	var o1, o2 uint32
	var t int64
	useAddi := false

	if target.IsBigEndian() {
		o1 = uint32(val >> 32)
		o2 = uint32(val)
	} else {
		o1 = uint32(val)
		o2 = uint32(val >> 32)
	}

	// On AIX, TOC data accesses are always made indirectly against R2 (a sequence of addis+ld+load/store). If the
	// The target of the load is known, the sequence can be written into addis+addi+load/store. On Linux,
	// TOC data accesses are always made directly against R2 (e.g addis+load/store).
	if target.IsAIX() {
		if !strings.HasPrefix(ldr.SymName(rs), "TOC.") {
			ldr.Errorf(s, "archreloctoc called for a symbol without TOC anchor")
		}
		relocs := ldr.Relocs(rs)
		tarSym := relocs.At(0).Sym()

		if target.IsInternal() && tarSym != 0 && ldr.AttrReachable(tarSym) && ldr.SymSect(tarSym).Seg == &ld.Segdata {
			t = ldr.SymValue(tarSym) + r.Add() - ldr.SymValue(syms.TOC)
			// change ld to addi in the second instruction
			o2 = (o2 & 0x03FF0000) | 0xE<<26
			useAddi = true
		} else {
			t = ldr.SymValue(rs) + r.Add() - ldr.SymValue(syms.TOC)
		}
	} else {
		t = ldr.SymValue(rs) + r.Add() - symtoc(ldr, syms, s)
	}

	if t != int64(int32(t)) {
		ldr.Errorf(s, "TOC relocation for %s is too big to relocate %s: 0x%x", ldr.SymName(s), rs, t)
	}

	if t&0x8000 != 0 {
		t += 0x10000
	}

	o1 |= uint32((t >> 16) & 0xFFFF)

	switch r.Type() {
	case objabi.R_ADDRPOWER_TOCREL_DS:
		if useAddi {
			o2 |= uint32(t) & 0xFFFF
		} else {
			if t&3 != 0 {
				ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
			}
			o2 |= uint32(t) & 0xFFFC
		}
	case objabi.R_ADDRPOWER_TOCREL:
		o2 |= uint32(t) & 0xffff
	default:
		return -1
	}

	if target.IsBigEndian() {
		return int64(o1)<<32 | int64(o2)
	}
	return int64(o2)<<32 | int64(o1)
}

// archrelocaddr relocates a symbol address.
// This code is for linux only.
func archrelocaddr(ldr *loader.Loader, target *ld.Target, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) int64 {
	rs := r.Sym()
	if target.IsAIX() {
		ldr.Errorf(s, "archrelocaddr called for %s relocation\n", ldr.SymName(rs))
	}
	o1, o2 := unpackInstPair(target, val)

	// Verify resulting address fits within a 31 bit (2GB) address space.
	// This is a restriction arising  from the usage of lis (HA) + d-form
	// (LO) instruction sequences used to implement absolute relocations
	// on PPC64 prior to ISA 3.1 (P10). For consistency, maintain this
	// restriction for ISA 3.1 unless it becomes problematic.
	t := ldr.SymAddr(rs) + r.Add()
	if t < 0 || t >= 1<<31 {
		ldr.Errorf(s, "relocation for %s is too big (>=2G): 0x%x", ldr.SymName(s), ldr.SymValue(rs))
	}

	// Note, relocations imported from external objects may not have cleared bits
	// within a relocatable field. They need cleared before applying the relocation.
	switch r.Type() {
	case objabi.R_ADDRPOWER_PCREL34:
		// S + A - P
		t -= (ldr.SymValue(s) + int64(r.Off()))
		o1 &^= 0x3ffff
		o2 &^= 0x0ffff
		o1 |= computePrefix34HI(t)
		o2 |= computeLO(int32(t))
	case objabi.R_ADDRPOWER_D34:
		o1 &^= 0x3ffff
		o2 &^= 0x0ffff
		o1 |= computePrefix34HI(t)
		o2 |= computeLO(int32(t))
	case objabi.R_ADDRPOWER:
		o1 &^= 0xffff
		o2 &^= 0xffff
		o1 |= computeHA(int32(t))
		o2 |= computeLO(int32(t))
	case objabi.R_ADDRPOWER_DS:
		o1 &^= 0xffff
		o2 &^= 0xfffc
		o1 |= computeHA(int32(t))
		o2 |= computeLO(int32(t))
		if t&3 != 0 {
			ldr.Errorf(s, "bad DS reloc for %s: %d", ldr.SymName(s), ldr.SymValue(rs))
		}
	default:
		return -1
	}

	return packInstPair(target, o1, o2)
}

// Determine if the code was compiled so that the TOC register R2 is initialized and maintained.
func r2Valid(ctxt *ld.Link) bool {
	return isLinkingPIC(ctxt)
}

// Determine if this is linking a position-independent binary.
func isLinkingPIC(ctxt *ld.Link) bool {
	switch ctxt.BuildMode {
	case ld.BuildModeCArchive, ld.BuildModeCShared, ld.BuildModePIE, ld.BuildModeShared, ld.BuildModePlugin:
		return true
	}
	// -linkshared option
	return ctxt.IsSharedGoLink()
}

// resolve direct jump relocation r in s, and add trampoline if necessary.
func trampoline(ctxt *ld.Link, ldr *loader.Loader, ri int, rs, s loader.Sym) {

	// Trampolines are created if the branch offset is too large and the linker cannot insert a call stub to handle it.
	// For internal linking, trampolines are always created for long calls.
	// For external linking, the linker can insert a call stub to handle a long call, but depends on having the TOC address in
	// r2.  For those build modes with external linking where the TOC address is not maintained in r2, trampolines must be created.
	if ctxt.IsExternal() && r2Valid(ctxt) {
		// The TOC pointer is valid. The external linker will insert trampolines.
		return
	}

	relocs := ldr.Relocs(s)
	r := relocs.At(ri)
	var t int64
	// ldr.SymValue(rs) == 0 indicates a cross-package jump to a function that is not yet
	// laid out. Conservatively use a trampoline. This should be rare, as we lay out packages
	// in dependency order.
	if ldr.SymValue(rs) != 0 {
		t = ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
	}
	switch r.Type() {
	case objabi.R_CALLPOWER:

		// If branch offset is too far then create a trampoline.

		if (ctxt.IsExternal() && ldr.SymSect(s) != ldr.SymSect(rs)) || (ctxt.IsInternal() && int64(int32(t<<6)>>6) != t) || ldr.SymValue(rs) == 0 || (*ld.FlagDebugTramp > 1 && ldr.SymPkg(s) != ldr.SymPkg(rs)) {
			var tramp loader.Sym
			for i := 0; ; i++ {

				// Using r.Add as part of the name is significant in functions like duffzero where the call
				// target is at some offset within the function.  Calls to duff+8 and duff+256 must appear as
				// distinct trampolines.

				oName := ldr.SymName(rs)
				name := oName
				if r.Add() == 0 {
					name += fmt.Sprintf("-tramp%d", i)
				} else {
					name += fmt.Sprintf("%+x-tramp%d", r.Add(), i)
				}

				// Look up the trampoline in case it already exists

				tramp = ldr.LookupOrCreateSym(name, int(ldr.SymVersion(rs)))
				if oName == "runtime.deferreturn" {
					ldr.SetIsDeferReturnTramp(tramp, true)
				}
				if ldr.SymValue(tramp) == 0 {
					break
				}
				// Note, the trampoline is always called directly. The addend of the original relocation is accounted for in the
				// trampoline itself.
				t = ldr.SymValue(tramp) - (ldr.SymValue(s) + int64(r.Off()))

				// With internal linking, the trampoline can be used if it is not too far.
				// With external linking, the trampoline must be in this section for it to be reused.
				if (ctxt.IsInternal() && int64(int32(t<<6)>>6) == t) || (ctxt.IsExternal() && ldr.SymSect(s) == ldr.SymSect(tramp)) {
					break
				}
			}
			if ldr.SymType(tramp) == 0 {
				trampb := ldr.MakeSymbolUpdater(tramp)
				ctxt.AddTramp(trampb)
				gentramp(ctxt, ldr, trampb, rs, r.Add())
			}
			sb := ldr.MakeSymbolUpdater(s)
			relocs := sb.Relocs()
			r := relocs.At(ri)
			r.SetSym(tramp)
			r.SetAdd(0) // This was folded into the trampoline target address
		}
	default:
		ctxt.Errorf(s, "trampoline called with non-jump reloc: %d (%s)", r.Type(), sym.RelocName(ctxt.Arch, r.Type()))
	}
}

func gentramp(ctxt *ld.Link, ldr *loader.Loader, tramp *loader.SymbolBuilder, target loader.Sym, offset int64) {
	tramp.SetSize(16) // 4 instructions
	P := make([]byte, tramp.Size())
	var o1, o2 uint32

	// ELFv2 save/restore functions use R0/R12 in special ways, therefore trampolines
	// as generated here will not always work correctly.
	if strings.HasPrefix(ldr.SymName(target), "runtime.elf_") {
		log.Fatalf("Internal linker does not support trampolines to ELFv2 ABI"+
			" register save/restore function %s", ldr.SymName(target))
	}

	if ctxt.IsAIX() {
		// On AIX, the address is retrieved with a TOC symbol.
		// For internal linking, the "Linux" way might still be used.
		// However, all text symbols are accessed with a TOC symbol as
		// text relocations aren't supposed to be possible.
		// So, keep using the external linking way to be more AIX friendly.
		o1 = uint32(OP_ADDIS_R12_R2) // addis r12,  r2, toctargetaddr hi
		o2 = uint32(OP_LD_R12_R12)   // ld    r12, r12, toctargetaddr lo

		toctramp := ldr.CreateSymForUpdate("TOC."+ldr.SymName(tramp.Sym()), 0)
		toctramp.SetType(sym.SXCOFFTOC)
		toctramp.AddAddrPlus(ctxt.Arch, target, offset)

		r, _ := tramp.AddRel(objabi.R_ADDRPOWER_TOCREL_DS)
		r.SetOff(0)
		r.SetSiz(8) // generates 2 relocations: HA + LO
		r.SetSym(toctramp.Sym())
	} else if hasPCrel {
		// pla r12, addr (PCrel). This works for static or PIC, with or without a valid TOC pointer.
		o1 = uint32(OP_PLA_PFX)
		o2 = uint32(OP_PLA_SFX_R12) // pla r12, addr

		// The trampoline's position is not known yet, insert a relocation.
		r, _ := tramp.AddRel(objabi.R_ADDRPOWER_PCREL34)
		r.SetOff(0)
		r.SetSiz(8) // This spans 2 words.
		r.SetSym(target)
		r.SetAdd(offset)
	} else {
		// Used for default build mode for an executable
		// Address of the call target is generated using
		// relocation and doesn't depend on r2 (TOC).
		o1 = uint32(OP_LIS_R12)      // lis  r12,targetaddr hi
		o2 = uint32(OP_ADDI_R12_R12) // addi r12,r12,targetaddr lo

		t := ldr.SymValue(target)
		if t == 0 || r2Valid(ctxt) || ctxt.IsExternal() {
			// Target address is unknown, generate relocations
			r, _ := tramp.AddRel(objabi.R_ADDRPOWER)
			if r2Valid(ctxt) {
				// Use a TOC relative address if R2 holds the TOC pointer
				o1 |= uint32(2 << 16) // Transform lis r31,ha into addis r31,r2,ha
				r.SetType(objabi.R_ADDRPOWER_TOCREL)
			}
			r.SetOff(0)
			r.SetSiz(8) // generates 2 relocations: HA + LO
			r.SetSym(target)
			r.SetAdd(offset)
		} else {
			// The target address is known, resolve it
			t += offset
			o1 |= (uint32(t) + 0x8000) >> 16 // HA
			o2 |= uint32(t) & 0xFFFF         // LO
		}
	}

	o3 := uint32(OP_MTCTR_R12) // mtctr r12
	o4 := uint32(OP_BCTR)      // bctr
	ctxt.Arch.ByteOrder.PutUint32(P, o1)
	ctxt.Arch.ByteOrder.PutUint32(P[4:], o2)
	ctxt.Arch.ByteOrder.PutUint32(P[8:], o3)
	ctxt.Arch.ByteOrder.PutUint32(P[12:], o4)
	tramp.SetData(P)
}

// Unpack a pair of 32 bit instruction words from
// a 64 bit relocation into instN and instN+1 in endian order.
func unpackInstPair(target *ld.Target, r int64) (uint32, uint32) {
	if target.IsBigEndian() {
		return uint32(r >> 32), uint32(r)
	}
	return uint32(r), uint32(r >> 32)
}

// Pack a pair of 32 bit instruction words o1, o2 into 64 bit relocation
// in endian order.
func packInstPair(target *ld.Target, o1, o2 uint32) int64 {
	if target.IsBigEndian() {
		return (int64(o1) << 32) | int64(o2)
	}
	return int64(o1) | (int64(o2) << 32)
}

// Compute the high-adjusted value (always a signed 32b value) per the ELF ABI.
// The returned value is always 0 <= x <= 0xFFFF.
func computeHA(val int32) uint32 {
	return uint32(uint16((val + 0x8000) >> 16))
}

// Compute the low value (the lower 16 bits of any 32b value) per the ELF ABI.
// The returned value is always 0 <= x <= 0xFFFF.
func computeLO(val int32) uint32 {
	return uint32(uint16(val))
}

// Compute the high 18 bits of a signed 34b constant. Used to pack the high 18 bits
// of a prefix34 relocation field. This assumes the input is already restricted to
// 34 bits.
func computePrefix34HI(val int64) uint32 {
	return uint32((val >> 16) & 0x3FFFF)
}

func computeTLSLEReloc(target *ld.Target, ldr *loader.Loader, rs, s loader.Sym) int64 {
	// The thread pointer points 0x7000 bytes after the start of the
	// thread local storage area as documented in section "3.7.2 TLS
	// Runtime Handling" of "Power Architecture 64-Bit ELF V2 ABI
	// Specification".
	v := ldr.SymValue(rs) - 0x7000
	if target.IsAIX() {
		// On AIX, the thread pointer points 0x7800 bytes after
		// the TLS.
		v -= 0x800
	}

	if int64(int32(v)) != v {
		ldr.Errorf(s, "TLS offset out of range %d", v)
	}
	return v
}

func archreloc(target *ld.Target, ldr *loader.Loader, syms *ld.ArchSyms, r loader.Reloc, s loader.Sym, val int64) (relocatedOffset int64, nExtReloc int, ok bool) {
	rs := r.Sym()
	if target.IsExternal() {
		// On AIX, relocations (except TLS ones) must be also done to the
		// value with the current addresses.
		switch rt := r.Type(); rt {
		default:
			if !target.IsAIX() {
				return val, nExtReloc, false
			}
		case objabi.R_POWER_TLS, objabi.R_POWER_TLS_IE_PCREL34, objabi.R_POWER_TLS_LE_TPREL34, objabi.R_ADDRPOWER_GOT_PCREL34:
			nExtReloc = 1
			return val, nExtReloc, true
		case objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE:
			if target.IsAIX() && rt == objabi.R_POWER_TLS_LE {
				// Fixup val, an addis/addi pair of instructions, which generate a 32b displacement
				// from the threadpointer (R13), into a 16b relocation. XCOFF only supports 16b
				// TLS LE relocations. Likewise, verify this is an addis/addi sequence.
				const expectedOpcodes = 0x3C00000038000000
				const expectedOpmasks = 0xFC000000FC000000
				if uint64(val)&expectedOpmasks != expectedOpcodes {
					ldr.Errorf(s, "relocation for %s+%d is not an addis/addi pair: %16x", ldr.SymName(rs), r.Off(), uint64(val))
				}
				nval := (int64(uint32(0x380d0000)) | val&0x03e00000) << 32 // addi rX, r13, $0
				nval |= int64(OP_NOP)                                      // nop
				val = nval
				nExtReloc = 1
			} else {
				nExtReloc = 2
			}
			return val, nExtReloc, true
		case objabi.R_ADDRPOWER,
			objabi.R_ADDRPOWER_DS,
			objabi.R_ADDRPOWER_TOCREL,
			objabi.R_ADDRPOWER_TOCREL_DS,
			objabi.R_ADDRPOWER_GOT,
			objabi.R_ADDRPOWER_PCREL:
			nExtReloc = 2 // need two ELF relocations, see elfreloc1
			if !target.IsAIX() {
				return val, nExtReloc, true
			}
		case objabi.R_CALLPOWER, objabi.R_ADDRPOWER_D34, objabi.R_ADDRPOWER_PCREL34:
			nExtReloc = 1
			if !target.IsAIX() {
				return val, nExtReloc, true
			}
		}
	}

	switch r.Type() {
	case objabi.R_ADDRPOWER_TOCREL, objabi.R_ADDRPOWER_TOCREL_DS:
		return archreloctoc(ldr, target, syms, r, s, val), nExtReloc, true
	case objabi.R_ADDRPOWER, objabi.R_ADDRPOWER_DS, objabi.R_ADDRPOWER_D34, objabi.R_ADDRPOWER_PCREL34:
		return archrelocaddr(ldr, target, syms, r, s, val), nExtReloc, true
	case objabi.R_CALLPOWER:
		// Bits 6 through 29 = (S + A - P) >> 2

		t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))

		tgtName := ldr.SymName(rs)

		// If we are linking PIE or shared code, non-PCrel golang generated object files have an extra 2 instruction prologue
		// to regenerate the TOC pointer from R12.  The exception are two special case functions tested below.  Note,
		// local call offsets for externally generated objects are accounted for when converting into golang relocs.
		if !hasPCrel && !ldr.AttrExternal(rs) && ldr.AttrShared(rs) && tgtName != "runtime.duffzero" && tgtName != "runtime.duffcopy" {
			// Furthermore, only apply the offset if the target looks like the start of a function call.
			if r.Add() == 0 && ldr.SymType(rs) == sym.STEXT {
				t += 8
			}
		}

		if t&3 != 0 {
			ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
		}
		// If branch offset is too far then create a trampoline.

		if int64(int32(t<<6)>>6) != t {
			ldr.Errorf(s, "direct call too far: %s %x", ldr.SymName(rs), t)
		}
		return val | int64(uint32(t)&^0xfc000003), nExtReloc, true
	case objabi.R_POWER_TOC: // S + A - .TOC.
		return ldr.SymValue(rs) + r.Add() - symtoc(ldr, syms, s), nExtReloc, true

	case objabi.R_ADDRPOWER_PCREL: // S + A - P
		t := ldr.SymValue(rs) + r.Add() - (ldr.SymValue(s) + int64(r.Off()))
		ha, l := unpackInstPair(target, val)
		l |= computeLO(int32(t))
		ha |= computeHA(int32(t))
		return packInstPair(target, ha, l), nExtReloc, true

	case objabi.R_POWER_TLS:
		const OP_ADD = 31<<26 | 266<<1
		const MASK_OP_ADD = 0x3F<<26 | 0x1FF<<1
		if val&MASK_OP_ADD != OP_ADD {
			ldr.Errorf(s, "R_POWER_TLS reloc only supports XO form ADD, not %08X", val)
		}
		// Verify RB is R13 in ADD RA,RB,RT.
		if (val>>11)&0x1F != 13 {
			// If external linking is made to support this, it may expect the linker to rewrite RB.
			ldr.Errorf(s, "R_POWER_TLS reloc requires R13 in RB (%08X).", uint32(val))
		}
		return val, nExtReloc, true

	case objabi.R_POWER_TLS_IE:
		// Convert TLS_IE relocation to TLS_LE if supported.
		if !(target.IsPIE() && target.IsElf()) {
			log.Fatalf("cannot handle R_POWER_TLS_IE (sym %s) when linking non-PIE, non-ELF binaries internally", ldr.SymName(s))
		}

		// We are an ELF binary, we can safely convert to TLS_LE from:
		// addis to, r2, x@got@tprel@ha
		// ld to, to, x@got@tprel@l(to)
		//
		// to TLS_LE by converting to:
		// addis to, r0, x@tprel@ha
		// addi to, to, x@tprel@l(to)

		const OP_MASK = 0x3F << 26
		const OP_RA_MASK = 0x1F << 16
		// convert r2 to r0, and ld to addi
		mask := packInstPair(target, OP_RA_MASK, OP_MASK)
		addi_op := packInstPair(target, 0, OP_ADDI)
		val &^= mask
		val |= addi_op
		fallthrough

	case objabi.R_POWER_TLS_LE:
		v := computeTLSLEReloc(target, ldr, rs, s)
		o1, o2 := unpackInstPair(target, val)
		o1 |= computeHA(int32(v))
		o2 |= computeLO(int32(v))
		return packInstPair(target, o1, o2), nExtReloc, true

	case objabi.R_POWER_TLS_IE_PCREL34:
		// Convert TLS_IE relocation to TLS_LE if supported.
		if !(target.IsPIE() && target.IsElf()) {
			log.Fatalf("cannot handle R_POWER_TLS_IE (sym %s) when linking non-PIE, non-ELF binaries internally", ldr.SymName(s))
		}

		// We are an ELF binary, we can safely convert to TLS_LE_TPREL34 from:
		// pld rX, x@got@tprel@pcrel
		//
		// to TLS_LE_TPREL32 by converting to:
		// pla rX, x@tprel

		const OP_MASK_PFX = 0xFFFFFFFF        // Discard prefix word
		const OP_MASK = (0x3F << 26) | 0xFFFF // Preserve RT, RA
		const OP_PFX = 1<<26 | 2<<24
		const OP_PLA = 14 << 26
		mask := packInstPair(target, OP_MASK_PFX, OP_MASK)
		pla_op := packInstPair(target, OP_PFX, OP_PLA)
		val &^= mask
		val |= pla_op
		fallthrough

	case objabi.R_POWER_TLS_LE_TPREL34:
		v := computeTLSLEReloc(target, ldr, rs, s)
		o1, o2 := unpackInstPair(target, val)
		o1 |= computePrefix34HI(v)
		o2 |= computeLO(int32(v))
		return packInstPair(target, o1, o2), nExtReloc, true
	}

	return val, nExtReloc, false
}

func archrelocvariant(target *ld.Target, ldr *loader.Loader, r loader.Reloc, rv sym.RelocVariant, s loader.Sym, t int64, p []byte) (relocatedOffset int64) {
	rs := r.Sym()
	switch rv & sym.RV_TYPE_MASK {
	default:
		ldr.Errorf(s, "unexpected relocation variant %d", rv)
		fallthrough

	case sym.RV_NONE:
		return t

	case sym.RV_POWER_LO:
		if rv&sym.RV_CHECK_OVERFLOW != 0 {
			// Whether to check for signed or unsigned
			// overflow depends on the instruction
			var o1 uint32
			if target.IsBigEndian() {
				o1 = binary.BigEndian.Uint32(p[r.Off()-2:])

			} else {
				o1 = binary.LittleEndian.Uint32(p[r.Off():])
			}
			switch o1 >> 26 {
			case 24, // ori
				26, // xori
				28: // andi
				if t>>16 != 0 {
					goto overflow
				}

			default:
				if int64(int16(t)) != t {
					goto overflow
				}
			}
		}

		return int64(int16(t))

	case sym.RV_POWER_HA:
		t += 0x8000
		fallthrough

		// Fallthrough
	case sym.RV_POWER_HI:
		t >>= 16

		if rv&sym.RV_CHECK_OVERFLOW != 0 {
			// Whether to check for signed or unsigned
			// overflow depends on the instruction
			var o1 uint32
			if target.IsBigEndian() {
				o1 = binary.BigEndian.Uint32(p[r.Off()-2:])
			} else {
				o1 = binary.LittleEndian.Uint32(p[r.Off():])
			}
			switch o1 >> 26 {
			case 25, // oris
				27, // xoris
				29: // andis
				if t>>16 != 0 {
					goto overflow
				}

			default:
				if int64(int16(t)) != t {
					goto overflow
				}
			}
		}

		return int64(int16(t))

	case sym.RV_POWER_DS:
		var o1 uint32
		if target.IsBigEndian() {
			o1 = uint32(binary.BigEndian.Uint16(p[r.Off():]))
		} else {
			o1 = uint32(binary.LittleEndian.Uint16(p[r.Off():]))
		}
		if t&3 != 0 {
			ldr.Errorf(s, "relocation for %s+%d is not aligned: %d", ldr.SymName(rs), r.Off(), t)
		}
		if (rv&sym.RV_CHECK_OVERFLOW != 0) && int64(int16(t)) != t {
			goto overflow
		}
		return int64(o1)&0x3 | int64(int16(t))
	}

overflow:
	ldr.Errorf(s, "relocation for %s+%d is too big: %d", ldr.SymName(rs), r.Off(), t)
	return t
}

func extreloc(target *ld.Target, ldr *loader.Loader, r loader.Reloc, s loader.Sym) (loader.ExtReloc, bool) {
	switch r.Type() {
	case objabi.R_POWER_TLS, objabi.R_POWER_TLS_LE, objabi.R_POWER_TLS_IE, objabi.R_POWER_TLS_IE_PCREL34, objabi.R_POWER_TLS_LE_TPREL34, objabi.R_CALLPOWER:
		return ld.ExtrelocSimple(ldr, r), true
	case objabi.R_ADDRPOWER,
		objabi.R_ADDRPOWER_DS,
		objabi.R_ADDRPOWER_TOCREL,
		objabi.R_ADDRPOWER_TOCREL_DS,
		objabi.R_ADDRPOWER_GOT,
		objabi.R_ADDRPOWER_GOT_PCREL34,
		objabi.R_ADDRPOWER_PCREL,
		objabi.R_ADDRPOWER_D34,
		objabi.R_ADDRPOWER_PCREL34:
		return ld.ExtrelocViaOuterSym(ldr, r, s), true
	}
	return loader.ExtReloc{}, false
}

func addpltsym(ctxt *ld.Link, ldr *loader.Loader, s loader.Sym) {
	if ldr.SymPlt(s) >= 0 {
		return
	}

	ld.Adddynsym(ldr, &ctxt.Target, &ctxt.ArchSyms, s)

	if ctxt.IsELF {
		plt := ldr.MakeSymbolUpdater(ctxt.PLT)
		rela := ldr.MakeSymbolUpdater(ctxt.RelaPLT)
		if plt.Size() == 0 {
			panic("plt is not set up")
		}

		// Create the glink resolver if necessary
		glink := ensureglinkresolver(ctxt, ldr)

		// Write symbol resolver stub (just a branch to the
		// glink resolver stub)
		rel, _ := glink.AddRel(objabi.R_CALLPOWER)
		rel.SetOff(int32(glink.Size()))
		rel.SetSiz(4)
		rel.SetSym(glink.Sym())
		glink.AddUint32(ctxt.Arch, 0x48000000) // b .glink

		// In the ppc64 ABI, the dynamic linker is responsible
		// for writing the entire PLT.  We just need to
		// reserve 8 bytes for each PLT entry and generate a
		// JMP_SLOT dynamic relocation for it.
		//
		// TODO(austin): ABI v1 is different
		ldr.SetPlt(s, int32(plt.Size()))

		plt.Grow(plt.Size() + 8)
		plt.SetSize(plt.Size() + 8)

		rela.AddAddrPlus(ctxt.Arch, plt.Sym(), int64(ldr.SymPlt(s)))
		rela.AddUint64(ctxt.Arch, elf.R_INFO(uint32(ldr.SymDynid(s)), uint32(elf.R_PPC64_JMP_SLOT)))
		rela.AddUint64(ctxt.Arch, 0)
	} else {
		ctxt.Errorf(s, "addpltsym: unsupported binary format")
	}
}

// Generate the glink resolver stub if necessary and return the .glink section.
func ensureglinkresolver(ctxt *ld.Link, ldr *loader.Loader) *loader.SymbolBuilder {
	glink := ldr.CreateSymForUpdate(".glink", 0)
	if glink.Size() != 0 {
		return glink
	}

	// This is essentially the resolver from the ppc64 ELFv2 ABI.
	// At entry, r12 holds the address of the symbol resolver stub
	// for the target routine and the argument registers hold the
	// arguments for the target routine.
	//
	// PC-rel offsets are computed once the final codesize of the
	// resolver is known.
	//
	// This stub is PIC, so first get the PC of label 1 into r11.
	glink.AddUint32(ctxt.Arch, OP_MFLR_R0) // mflr r0
	glink.AddUint32(ctxt.Arch, OP_BCL_NIA) // bcl 20,31,1f
	glink.AddUint32(ctxt.Arch, 0x7d6802a6) // 1: mflr r11
	glink.AddUint32(ctxt.Arch, OP_MTLR_R0) // mtlr r0

	// Compute the .plt array index from the entry point address
	// into r0. This is computed relative to label 1 above.
	glink.AddUint32(ctxt.Arch, 0x38000000) // li r0,-(res_0-1b)
	glink.AddUint32(ctxt.Arch, 0x7c006214) // add r0,r0,r12
	glink.AddUint32(ctxt.Arch, 0x7c0b0050) // sub r0,r0,r11
	glink.AddUint32(ctxt.Arch, 0x7800f082) // srdi r0,r0,2

	// Load the PC-rel offset of ".plt - 1b", and add it to 1b.
	// This is stored after this stub and before the resolvers.
	glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,res_0-1b-8(r11)
	glink.AddUint32(ctxt.Arch, 0x7d6b6214) // add r11,r11,r12

	// Load r12 = dynamic resolver address and r11 = DSO
	// identifier from the first two doublewords of the PLT.
	glink.AddUint32(ctxt.Arch, 0xe98b0000) // ld r12,0(r11)
	glink.AddUint32(ctxt.Arch, 0xe96b0008) // ld r11,8(r11)

	// Jump to the dynamic resolver
	glink.AddUint32(ctxt.Arch, OP_MTCTR_R12) // mtctr r12
	glink.AddUint32(ctxt.Arch, OP_BCTR)      // bctr

	// Store the PC-rel offset to the PLT
	r, _ := glink.AddRel(objabi.R_PCREL)
	r.SetSym(ctxt.PLT)
	r.SetSiz(8)
	r.SetOff(int32(glink.Size()))
	r.SetAdd(glink.Size())        // Adjust the offset to be relative to label 1 above.
	glink.AddUint64(ctxt.Arch, 0) // The offset to the PLT.

	// Resolve PC-rel offsets above now the final size of the stub is known.
	res0m1b := glink.Size() - 8 // res_0 - 1b
	glink.SetUint32(ctxt.Arch, 16, 0x38000000|uint32(uint16(-res0m1b)))
	glink.SetUint32(ctxt.Arch, 32, 0xe98b0000|uint32(uint16(res0m1b-8)))

	// The symbol resolvers must immediately follow.
	//   res_0:

	// Add DT_PPC64_GLINK .dynamic entry, which points to 32 bytes
	// before the first symbol resolver stub.
	du := ldr.MakeSymbolUpdater(ctxt.Dynamic)
	ld.Elfwritedynentsymplus(ctxt, du, elf.DT_PPC64_GLINK, glink.Sym(), glink.Size()-32)

	return glink
}
