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