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