machrel.sparc.c revision 2647:e440e3da2a6f
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 *	Copyright (c) 1988 AT&T
24 *	  All Rights Reserved
25 *
26 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
27 * Use is subject to license terms.
28 */
29#pragma ident	"%Z%%M%	%I%	%E% SMI"
30
31#include	<string.h>
32#include	<stdio.h>
33#include	<sys/elf_SPARC.h>
34#include	<debug.h>
35#include	<reloc.h>
36#include	"msg.h"
37#include	"_libld.h"
38
39/*
40 * Local Variable Definitions
41 */
42static Sword neggotoffset = 0;		/* off. of GOT table from GOT symbol */
43static Sword smlgotcnt = M_GOT_XNumber;	/* no. of small GOT symbols */
44
45Word
46ld_init_rel(Rel_desc *reld, void *reloc)
47{
48	Rela *	rela = (Rela *)reloc;
49
50	/* LINTED */
51	reld->rel_rtype = (Word)ELF_R_TYPE(rela->r_info);
52	reld->rel_roffset = rela->r_offset;
53	reld->rel_raddend = rela->r_addend;
54	reld->rel_typedata = (Word)ELF_R_TYPE_DATA(rela->r_info);
55
56	reld->rel_flags |= FLG_REL_RELA;
57
58	return ((Word)ELF_R_SYM(rela->r_info));
59}
60
61void
62ld_mach_eflags(Ehdr *ehdr, Ofl_desc *ofl)
63{
64	Word		eflags = ofl->ofl_dehdr->e_flags;
65	Word		memopt1, memopt2;
66	static int	firstpass;
67
68	/*
69	 * If a *PLUS relocatable is included, the output object is type *PLUS.
70	 */
71	if ((ehdr->e_machine == EM_SPARC32PLUS) &&
72	    (ehdr->e_flags & EF_SPARC_32PLUS))
73		ofl->ofl_dehdr->e_machine = EM_SPARC32PLUS;
74
75	/*
76	 * On the first pass, we don't yet have a memory model to compare
77	 * against, therefore the initial file becomes our baseline.  Subsequent
78	 * passes will do the comparison described below.
79	 */
80	if (firstpass == 0) {
81		ofl->ofl_dehdr->e_flags |= ehdr->e_flags;
82		firstpass++;
83		return;
84	}
85
86	/*
87	 * Determine which memory model to mark the binary with.  The options
88	 * are (most restrictive to least):
89	 *
90	 *	EF_SPARCV9_TSO		0x0 	Total Store Order
91	 *	EF_SPARCV9_PSO		0x1	Partial Store Order
92	 *	EF_SPARCV9_RMO		0x2	Relaxed Memory Order
93	 *
94	 * Mark the binary with the most restrictive option encountered from a
95	 * relocatable object included in the link.
96	 */
97	eflags |= (ehdr->e_flags & ~EF_SPARCV9_MM);
98	memopt1 = eflags & EF_SPARCV9_MM;
99	memopt2 = ehdr->e_flags & EF_SPARCV9_MM;
100	eflags &= ~EF_SPARCV9_MM;
101
102	if ((memopt1 == EF_SPARCV9_TSO) || (memopt2 == EF_SPARCV9_TSO))
103		/* EMPTY */
104		;
105	else if ((memopt1 == EF_SPARCV9_PSO) || (memopt2 == EF_SPARCV9_PSO))
106		eflags |= EF_SPARCV9_PSO;
107	else
108		eflags |= EF_SPARCV9_RMO;
109
110	ofl->ofl_dehdr->e_flags = eflags;
111}
112
113void
114ld_mach_make_dynamic(Ofl_desc *ofl, size_t *cnt)
115{
116	if (!(ofl->ofl_flags & FLG_OF_RELOBJ)) {
117		/*
118		 * Create this entry if we are going to create a PLT table.
119		 */
120		if (ofl->ofl_pltcnt)
121			(*cnt)++;		/* DT_PLTGOT */
122	}
123}
124
125void
126ld_mach_update_odynamic(Ofl_desc *ofl, Dyn **dyn)
127{
128	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && ofl->ofl_pltcnt) {
129		(*dyn)->d_tag = DT_PLTGOT;
130		if (ofl->ofl_osplt)
131			(*dyn)->d_un.d_ptr = ofl->ofl_osplt->os_shdr->sh_addr;
132		else
133			(*dyn)->d_un.d_ptr = 0;
134		(*dyn)++;
135	}
136}
137
138#if	defined(_ELF64)
139
140Xword
141ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl)
142{
143	Xword	value, pltndx, farpltndx;
144
145	pltndx = sdp->sd_aux->sa_PLTndx + M_PLT_XNumber - 1;
146
147	if ((pltndx) < M64_PLT_NEARPLTS) {
148		value = (Xword)(ofl->ofl_osplt->os_shdr->sh_addr) +
149		    (pltndx * M_PLT_ENTSIZE);
150		return (value);
151	}
152
153	farpltndx = pltndx - M64_PLT_NEARPLTS;
154
155	/*
156	 * pltoffset of a far plt is calculated by:
157	 *
158	 *	<size of near plt table> +
159	 *	<size of preceding far plt blocks> +
160	 *	<blockndx * sizeof (far plt entsize)>
161	 */
162	value =
163	    /* size of near plt table */
164	    (M64_PLT_NEARPLTS * M_PLT_ENTSIZE) +
165	    /* size of preceding far plt blocks */
166	    ((farpltndx / M64_PLT_FBLKCNTS) *
167	    ((M64_PLT_FENTSIZE + sizeof (Addr)) *
168	    M64_PLT_FBLKCNTS)) +
169	    /* pltblockendx * fentsize */
170	    ((farpltndx % M64_PLT_FBLKCNTS) * M64_PLT_FENTSIZE);
171
172	value += (Xword)(ofl->ofl_osplt->os_shdr->sh_addr);
173	return (value);
174}
175
176/*
177 * Instructions required for Far PLT's
178 */
179static uint32_t farplt_instrs[6] = {
180	0x8a10000f,			/* mov   %o7, %g5	*/
181	0x40000002,			/* call  . + 0x8	*/
182	0x01000000,			/* nop			*/
183	0xc25be000,			/* ldx   [%o7 + 0], %g1	*/
184	0x83c3c001,			/* jmpl  %o7 + %g1, %g1	*/
185	0x9e100005			/* mov   %g5, %o7	*/
186};
187
188/*
189 * Far PLT'S:
190 *
191 * Far PLT's are established in blocks of '160' at a time.  These
192 * PLT's consist of 6 instructions (24 bytes) and 1 pointer (8 bytes).
193 * The instructions are collected together in blocks of 160 entries
194 * followed by 160 pointers.  The last group of entries and pointers
195 * may contain less then 160 items.  No padding is required.
196 *
197 *	.PLT32768:
198 *		mov	%o7, %g5
199 *		call	. + 8
200 *		nop
201 *		ldx	[%o7 + .PLTP32768 - (.PLT32768 + 4)], %g1
202 *		jmpl	%o7 + %g1, %g1
203 *		mov	%g5, %o7
204 *	................................
205 *	.PLT32927:
206 *		mov	%o7, %g5
207 *		call	. + 8
208 *		nop
209 *		ldx	[%o7 + .PLTP32927 - (.PLT32927 + 4)], %g1
210 *		jmpl	%o7 + %g1, %g1
211 *		mov	%g5, %o7
212 *	.PLTP32768:
213 *		.xword .PLT0-(.PLT32768+4)
214 *	................................
215 *	.PLTP32927:
216 *		.xword .PLT0-(.PLT32927+4)
217 *
218 */
219void
220plt_far_entry(Ofl_desc *ofl, Xword pltndx, Xword *roffset, Sxword *raddend)
221{
222	uint_t		blockndx;	/* # of far PLT blocks */
223	uint_t		farblkcnt;	/* Index to far PLT block */
224	Xword		farpltndx;	/* index of Far Plt */
225	Xword		farpltblkndx;	/* index of PLT in BLOCK */
226	uint32_t	*pltent;	/* ptr to plt instr. sequence */
227	uint64_t	*pltentptr;	/* ptr to plt addr ptr */
228	Sxword		pltblockoff;	/* offset to Far plt block */
229	Sxword		pltoff;		/* offset to PLT instr. sequence */
230	Sxword		pltptroff;	/* offset to PLT addr ptr */
231	uchar_t		*pltbuf;	/* ptr to PLT's in file */
232
233
234	farblkcnt = ((ofl->ofl_pltcnt - 1 +
235		M_PLT_XNumber - M64_PLT_NEARPLTS) / M64_PLT_FBLKCNTS);
236
237	/*
238	 * Determine the 'Far' PLT index.
239	 */
240	farpltndx = pltndx - 1 + M_PLT_XNumber - M64_PLT_NEARPLTS;
241	farpltblkndx = farpltndx % M64_PLT_FBLKCNTS;
242
243	/*
244	 * Determine what FPLT block this plt falls into.
245	 */
246	blockndx = (uint_t)(farpltndx / M64_PLT_FBLKCNTS);
247
248	/*
249	 * Calculate the starting offset of the Far PLT block
250	 * that this PLT is a member of.
251	 */
252	pltblockoff = (M64_PLT_NEARPLTS * M_PLT_ENTSIZE) +
253		(blockndx * M64_PLT_FBLOCKSZ);
254
255	pltoff = pltblockoff +
256		(farpltblkndx * M64_PLT_FENTSIZE);
257
258	pltptroff = pltblockoff;
259
260
261	if (farblkcnt > blockndx) {
262		/*
263		 * If this is a full block - the 'pltptroffs' start
264		 * after 160 fplts.
265		 */
266		pltptroff += (M64_PLT_FBLKCNTS * M64_PLT_FENTSIZE) +
267			(farpltblkndx * M64_PLT_PSIZE);
268	} else {
269		Xword	lastblkpltndx;
270		/*
271		 * If this is the last block - the the pltptr's start
272		 * after the last FPLT instruction sequence.
273		 */
274		lastblkpltndx = (ofl->ofl_pltcnt - 1 + M_PLT_XNumber -
275			M64_PLT_NEARPLTS) % M64_PLT_FBLKCNTS;
276		pltptroff += ((lastblkpltndx + 1) * M64_PLT_FENTSIZE) +
277			(farpltblkndx * M64_PLT_PSIZE);
278	}
279	pltbuf = (uchar_t *)ofl->ofl_osplt->os_outdata->d_buf;
280
281	/*
282	 * For far-plts, the Raddend and Roffset fields are defined
283	 * to be:
284	 *
285	 *	roffset:	address of .PLTP#
286	 *	raddend:	-(.PLT#+4)
287	 */
288	*roffset = pltptroff + (Xword)(ofl->ofl_osplt->os_shdr->sh_addr);
289	*raddend = -(pltoff + 4 + (Xword)(ofl->ofl_osplt->os_shdr->sh_addr));
290
291	/* LINTED */
292	pltent = (uint32_t *)(pltbuf + pltoff);
293	/* LINTED */
294	pltentptr = (uint64_t *)(pltbuf + pltptroff);
295	(void) memcpy(pltent, farplt_instrs, sizeof (farplt_instrs));
296
297	/*
298	 *  update
299	 *	ldx   [%o7 + 0], %g1
300	 * to
301	 *	ldx   [%o7 + .PLTP# - (.PLT# + 4)], %g1
302	 */
303	/* LINTED */
304	pltent[3] |= (uint32_t)(pltptroff - (pltoff + 4));
305
306	/*
307	 * Store:
308	 *	.PLTP#
309	 *		.xword	.PLT0 - .PLT# + 4
310	 */
311	*pltentptr = -(pltoff + 4);
312}
313
314/*
315 *	Build a single V9 P.L.T. entry - code is:
316 *
317 *	For Target Addresses +/- 4GB of the entry
318 *	-----------------------------------------
319 *	sethi	(. - .PLT0), %g1
320 *	ba,a	%xcc, .PLT1
321 *	nop
322 *	nop
323 *	nop
324 *	nop
325 *	nop
326 *	nop
327 *
328 *	For Target Addresses +/- 2GB of the entry
329 *	-----------------------------------------
330 *
331 *	.PLT0 is the address of the first entry in the P.L.T.
332 *	This one is filled in by the run-time link editor. We just
333 *	have to leave space for it.
334 */
335static void
336plt_entry(Ofl_desc *ofl, Xword pltndx, Xword *roffset, Sxword *raddend)
337{
338	uchar_t		*pltent;	/* PLT entry being created. */
339	Sxword		pltoff;		/* Offset of this entry from PLT top */
340
341	/*
342	 *  The second part of the V9 ABI (sec. 5.2.4)
343	 *  applies to plt entries greater than 0x8000 (32,768).
344	 *  This is handled in 'plt_far_entry()'
345	 */
346	if ((pltndx - 1 + M_PLT_XNumber) >= M64_PLT_NEARPLTS) {
347		plt_far_entry(ofl, pltndx, roffset, raddend);
348		return;
349	}
350
351	pltoff = M_PLT_RESERVSZ + (pltndx - 1) * M_PLT_ENTSIZE;
352	pltent = (uchar_t *)ofl->ofl_osplt->os_outdata->d_buf +
353		pltoff;
354
355	*roffset = pltoff + (Xword)(ofl->ofl_osplt->os_shdr->sh_addr);
356	*raddend = 0;
357
358	/*
359	 * PLT[0]: sethi %hi(. - .L0), %g1
360	 */
361	/* LINTED */
362	*(Word *)pltent = M_SETHIG1 | pltoff;
363
364	/*
365	 * PLT[1]: ba,a %xcc, .PLT1 (.PLT1 accessed as a
366	 * PC-relative index of longwords).
367	 */
368	pltent += M_PLT_INSSIZE;
369	pltoff += M_PLT_INSSIZE;
370	pltoff = -pltoff;
371	/* LINTED */
372	*(Word *)pltent = M_BA_A_XCC |
373		(((pltoff + M_PLT_ENTSIZE) >> 2) & S_MASK(19));
374
375	/*
376	 * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI).
377	 */
378	pltent += M_PLT_INSSIZE;
379	/* LINTED */
380	*(Word *)pltent = M_NOP;
381
382	/*
383	 * PLT[3]: sethi 0, %g0 (NOP for PLT padding).
384	 */
385	pltent += M_PLT_INSSIZE;
386	/* LINTED */
387	*(Word *)pltent = M_NOP;
388
389	/*
390	 * PLT[4]: sethi 0, %g0 (NOP for PLT padding).
391	 */
392	pltent += M_PLT_INSSIZE;
393	/* LINTED */
394	*(Word *)pltent = M_NOP;
395
396	/*
397	 * PLT[5]: sethi 0, %g0 (NOP for PLT padding).
398	 */
399	pltent += M_PLT_INSSIZE;
400	/* LINTED */
401	*(Word *)pltent = M_NOP;
402
403	/*
404	 * PLT[6]: sethi 0, %g0 (NOP for PLT padding).
405	 */
406	pltent += M_PLT_INSSIZE;
407	/* LINTED */
408	*(Word *)pltent = M_NOP;
409
410	/*
411	 * PLT[7]: sethi 0, %g0 (NOP for PLT padding).
412	 */
413	pltent += M_PLT_INSSIZE;
414	/* LINTED */
415	*(Word *)pltent = M_NOP;
416}
417
418
419#else  /* Elf 32 */
420
421Xword
422ld_calc_plt_addr(Sym_desc *sdp, Ofl_desc *ofl)
423{
424	Xword	value, pltndx;
425
426	pltndx = sdp->sd_aux->sa_PLTndx + M_PLT_XNumber - 1;
427	value = (Xword)(ofl->ofl_osplt->os_shdr->sh_addr) +
428	    (pltndx * M_PLT_ENTSIZE);
429	return (value);
430}
431
432
433/*
434 *	Build a single P.L.T. entry - code is:
435 *
436 *	sethi	(. - .L0), %g1
437 *	ba,a	.L0
438 *	sethi	0, %g0		(nop)
439 *
440 *	.L0 is the address of the first entry in the P.L.T.
441 *	This one is filled in by the run-time link editor. We just
442 *	have to leave space for it.
443 */
444static void
445plt_entry(Ofl_desc * ofl, Xword pltndx, Xword *roffset, Sxword *raddend)
446{
447	Byte *	pltent;	/* PLT entry being created. */
448	Sxword	pltoff;	/* Offset of this entry from PLT top */
449
450	pltoff = M_PLT_RESERVSZ + (pltndx - 1) * M_PLT_ENTSIZE;
451	pltent = (Byte *)ofl->ofl_osplt->os_outdata->d_buf + pltoff;
452
453	*roffset = pltoff + (Xword)(ofl->ofl_osplt->os_shdr->sh_addr);
454	*raddend = 0;
455
456	/*
457	 * PLT[0]: sethi %hi(. - .L0), %g1
458	 */
459	/* LINTED */
460	*(Word *)pltent = M_SETHIG1 | pltoff;
461
462	/*
463	 * PLT[1]: ba,a .L0 (.L0 accessed as a PC-relative index of longwords)
464	 */
465	pltent += M_PLT_INSSIZE;
466	pltoff += M_PLT_INSSIZE;
467	pltoff = -pltoff;
468	/* LINTED */
469	*(Word *)pltent = M_BA_A | ((pltoff >> 2) & S_MASK(22));
470
471	/*
472	 * PLT[2]: sethi 0, %g0 (NOP for delay slot of eventual CTI).
473	 */
474	pltent += M_PLT_INSSIZE;
475	/* LINTED */
476	*(Word *)pltent = M_SETHIG0;
477
478	/*
479	 * PLT[3]: sethi 0, %g0 (NOP for PLT padding).
480	 */
481	pltent += M_PLT_INSSIZE;
482	/* LINTED */
483	*(Word *)pltent = M_SETHIG0;
484}
485
486#endif /* _ELF64 */
487
488uintptr_t
489ld_perform_outreloc(Rel_desc * orsp, Ofl_desc * ofl)
490{
491	Os_desc *		relosp, * osp = 0;
492	Xword			ndx, roffset, value;
493	Sxword			raddend;
494	const Rel_entry *	rep;
495	Rela			rea;
496	char			*relbits;
497	Sym_desc *		sdp, * psym = (Sym_desc *)0;
498	int			sectmoved = 0;
499	Word			dtflags1 = ofl->ofl_dtflags_1;
500	Word			flags = ofl->ofl_flags;
501
502	raddend = orsp->rel_raddend;
503	sdp = orsp->rel_sym;
504
505	/*
506	 * Special case, a regsiter symbol associated with symbol
507	 * index 0 is initialized (i.e. relocated) to a constant
508	 * in the r_addend field rather than to a symbol value.
509	 */
510	if ((orsp->rel_rtype == M_R_REGISTER) && !sdp) {
511		relosp = ofl->ofl_osrel;
512		relbits = (char *)relosp->os_outdata->d_buf;
513
514		rea.r_info = ELF_R_INFO(0,
515		    ELF_R_TYPE_INFO(orsp->rel_typedata, orsp->rel_rtype));
516		rea.r_offset = orsp->rel_roffset;
517		rea.r_addend = raddend;
518		DBG_CALL(Dbg_reloc_out(ofl, ELF_DBG_LD, SHT_RELA, &rea,
519		    relosp->os_name, orsp->rel_sname));
520
521		assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
522		(void) memcpy((relbits + relosp->os_szoutrels),
523		    (char *)&rea, sizeof (Rela));
524		relosp->os_szoutrels += (Xword)sizeof (Rela);
525
526		return (1);
527	}
528
529	/*
530	 * If the section this relocation is against has been discarded
531	 * (-zignore), then also discard (skip) the relocation itself.
532	 */
533	if (orsp->rel_isdesc && ((orsp->rel_flags &
534	    (FLG_REL_GOT | FLG_REL_BSS | FLG_REL_PLT | FLG_REL_NOINFO)) == 0) &&
535	    (orsp->rel_isdesc->is_flags & FLG_IS_DISCARD)) {
536		DBG_CALL(Dbg_reloc_discard(ofl->ofl_lml, M_MACH, orsp));
537		return (1);
538	}
539
540	/*
541	 * If this is a relocation against a move table, or expanded move
542	 * table, adjust the relocation entries.
543	 */
544	if (orsp->rel_move)
545		ld_adj_movereloc(ofl, orsp);
546
547	/*
548	 * If this is a relocation against a section then we need to adjust the
549	 * raddend field to compensate for the new position of the input section
550	 * within the new output section.
551	 */
552	if (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) {
553		if (ofl->ofl_parsym.head &&
554		    (sdp->sd_isc->is_flags & FLG_IS_RELUPD) &&
555		    (psym = ld_am_I_partial(orsp, orsp->rel_raddend))) {
556			/*
557			 * If the symbol is moved, adjust the value
558			 */
559			DBG_CALL(Dbg_move_outsctadj(ofl->ofl_lml, psym));
560			sectmoved = 1;
561			if (ofl->ofl_flags & FLG_OF_RELOBJ)
562				raddend = psym->sd_sym->st_value;
563			else
564				raddend = psym->sd_sym->st_value -
565				    psym->sd_isc->is_osdesc->os_shdr->sh_addr;
566			/* LINTED */
567			raddend += (Off)_elf_getxoff(psym->sd_isc->is_indata);
568			if (psym->sd_isc->is_shdr->sh_flags & SHF_ALLOC)
569				raddend +=
570				psym->sd_isc->is_osdesc->os_shdr->sh_addr;
571		} else {
572			/* LINTED */
573			raddend += (Off)_elf_getxoff(sdp->sd_isc->is_indata);
574			if (sdp->sd_isc->is_shdr->sh_flags & SHF_ALLOC)
575				raddend +=
576				sdp->sd_isc->is_osdesc->os_shdr->sh_addr;
577		}
578	}
579
580	value = sdp->sd_sym->st_value;
581
582	if (orsp->rel_flags & FLG_REL_GOT) {
583		osp = ofl->ofl_osgot;
584		roffset = ld_calc_got_offset(orsp, ofl);
585
586	} else if (orsp->rel_flags & FLG_REL_PLT) {
587		osp = ofl->ofl_osplt;
588		plt_entry(ofl, sdp->sd_aux->sa_PLTndx, &roffset, &raddend);
589	} else if (orsp->rel_flags & FLG_REL_BSS) {
590		/*
591		 * This must be a R_SPARC_COPY.  For these set the roffset to
592		 * point to the new symbols location.
593		 */
594		osp = ofl->ofl_isbss->is_osdesc;
595		roffset = (Xword)value;
596
597		/*
598		 * The raddend doesn't mean anything in an R_SPARC_COPY
599		 * relocation.  Null it out because it can confuse people.
600		 */
601		raddend = 0;
602	} else if (orsp->rel_flags & FLG_REL_REG) {
603		/*
604		 * The offsets of relocations against register symbols
605		 * identifiy the register directly - so the offset
606		 * does not need to be adjusted.
607		 */
608		roffset = orsp->rel_roffset;
609	} else {
610		osp = orsp->rel_osdesc;
611
612		/*
613		 * Calculate virtual offset of reference point; equals offset
614		 * into section + vaddr of section for loadable sections, or
615		 * offset plus section displacement for nonloadable sections.
616		 */
617		roffset = orsp->rel_roffset +
618		    (Off)_elf_getxoff(orsp->rel_isdesc->is_indata);
619		if (!(ofl->ofl_flags & FLG_OF_RELOBJ))
620			roffset += orsp->rel_isdesc->is_osdesc->
621			    os_shdr->sh_addr;
622	}
623
624	if ((osp == 0) || ((relosp = osp->os_relosdesc) == 0))
625		relosp = ofl->ofl_osrel;
626
627	/*
628	 * Verify that the output relocations offset meets the
629	 * alignment requirements of the relocation being processed.
630	 */
631	rep = &reloc_table[orsp->rel_rtype];
632	if (((flags & FLG_OF_RELOBJ) || !(dtflags1 & DF_1_NORELOC)) &&
633	    !(rep->re_flags & FLG_RE_UNALIGN)) {
634		if (((rep->re_fsize == 2) && (roffset & 0x1)) ||
635		    ((rep->re_fsize == 4) && (roffset & 0x3)) ||
636		    ((rep->re_fsize == 8) && (roffset & 0x7))) {
637			eprintf(ofl->ofl_lml, ERR_FATAL,
638			    MSG_INTL(MSG_REL_NONALIGN),
639			    conv_reloc_SPARC_type(orsp->rel_rtype, 0),
640			    orsp->rel_isdesc->is_file->ifl_name,
641			    demangle(orsp->rel_sname), EC_XWORD(roffset));
642			return (S_ERROR);
643		}
644	}
645
646	/*
647	 * Assign the symbols index for the output relocation.  If the
648	 * relocation refers to a SECTION symbol then it's index is based upon
649	 * the output sections symbols index.  Otherwise the index can be
650	 * derived from the symbols index itself.
651	 */
652	if (orsp->rel_rtype == R_SPARC_RELATIVE)
653		ndx = STN_UNDEF;
654	else if ((orsp->rel_flags & FLG_REL_SCNNDX) ||
655	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
656		if (sectmoved == 0) {
657			/*
658			 * Check for a null input section. This can
659			 * occur if this relocation references a symbol
660			 * generated by sym_add_sym().
661			 */
662			if ((sdp->sd_isc != 0) &&
663			    (sdp->sd_isc->is_osdesc != 0))
664				ndx = sdp->sd_isc->is_osdesc->os_scnsymndx;
665			else
666				ndx = sdp->sd_shndx;
667		} else
668			ndx = ofl->ofl_sunwdata1ndx;
669	} else
670		ndx = sdp->sd_symndx;
671
672	/*
673	 * Add the symbols 'value' to the addend field.
674	 */
675	if (orsp->rel_flags & FLG_REL_ADVAL)
676		raddend += value;
677
678	/*
679	 * The addend field for R_SPARC_TLS_DTPMOD32 and R_SPARC_TLS_DTPMOD64
680	 * mean nothing.  The addend is propagated in the corresponding
681	 * R_SPARC_TLS_DTPOFF* relocations.
682	 */
683	if (orsp->rel_rtype == M_R_DTPMOD)
684		raddend = 0;
685
686	relbits = (char *)relosp->os_outdata->d_buf;
687
688	rea.r_info = ELF_R_INFO(ndx, ELF_R_TYPE_INFO(orsp->rel_typedata,
689			orsp->rel_rtype));
690	rea.r_offset = roffset;
691	rea.r_addend = raddend;
692	DBG_CALL(Dbg_reloc_out(ofl, ELF_DBG_LD, SHT_RELA, &rea, relosp->os_name,
693	    orsp->rel_sname));
694
695	/*
696	 * Assert we haven't walked off the end of our relocation table.
697	 */
698	assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
699
700	(void) memcpy((relbits + relosp->os_szoutrels),
701	    (char *)&rea, sizeof (Rela));
702	relosp->os_szoutrels += (Xword)sizeof (Rela);
703
704	/*
705	 * Determine if this relocation is against a non-writable, allocatable
706	 * section.  If so we may need to provide a text relocation diagnostic.
707	 */
708	ld_reloc_remain_entry(orsp, osp, ofl);
709	return (1);
710}
711
712
713/*
714 * Sparc Instructions for TLS processing
715 */
716#if	defined(_ELF64)
717#define	TLS_GD_IE_LD	0xd0580000	/* ldx [%g0 + %g0], %o0 */
718#else
719#define	TLS_GD_IE_LD	0xd0000000	/* ld [%g0 + %g0], %o0 */
720#endif
721#define	TLS_GD_IE_ADD	0x9001c008	/* add %g7, %o0, %o0 */
722
723#define	TLS_GD_LE_XOR	0x80182000	/* xor %g0, 0, %g0 */
724#define	TLS_IE_LE_OR	0x80100000	/* or %g0, %o0, %o1 */
725					/*  synthetic: mov %g0, %g0 */
726
727#define	TLS_LD_LE_CLRO0	0x90100000	/* clr	%o0 */
728
729#define	FM3_REG_MSK_RD	(0x1f << 25)	/* Formate (3) rd register mask */
730					/*	bits 25->29 */
731#define	FM3_REG_MSK_RS1	(0x1f << 14)	/* Formate (3) rs1 register mask */
732					/*	bits 14->18 */
733#define	FM3_REG_MSK_RS2	0x1f		/* Formate (3) rs2 register mask */
734					/*	bits 0->4 */
735
736#define	REG_G7		7		/* %g7 register */
737
738static Fixupret
739tls_fixups(Ofl_desc *ofl, Rel_desc *arsp)
740{
741	Sym_desc	*sdp = arsp->rel_sym;
742	Word		rtype = arsp->rel_rtype;
743	uint_t		*offset;
744
745	offset = (uint_t *)((uintptr_t)arsp->rel_roffset +
746		(uintptr_t)_elf_getxoff(arsp->rel_isdesc->is_indata) +
747		(uintptr_t)arsp->rel_osdesc->os_outdata->d_buf);
748
749	if (sdp->sd_ref == REF_DYN_NEED) {
750		/*
751		 * IE reference model
752		 */
753		switch (rtype) {
754		case R_SPARC_TLS_GD_HI22:
755			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
756			    rtype, R_SPARC_TLS_IE_HI22, arsp->rel_roffset,
757			    sdp->sd_name));
758			arsp->rel_rtype = R_SPARC_TLS_IE_HI22;
759			return (FIX_RELOC);
760
761		case R_SPARC_TLS_GD_LO10:
762			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
763			    rtype, R_SPARC_TLS_IE_LO10, arsp->rel_roffset,
764			    sdp->sd_name));
765			arsp->rel_rtype = R_SPARC_TLS_IE_LO10;
766			return (FIX_RELOC);
767
768		case R_SPARC_TLS_GD_ADD:
769			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
770			    rtype, R_SPARC_NONE, arsp->rel_roffset,
771			    sdp->sd_name));
772			*offset = (TLS_GD_IE_LD |
773			    (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RS2)));
774			return (FIX_DONE);
775
776		case R_SPARC_TLS_GD_CALL:
777			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
778			    rtype, R_SPARC_NONE, arsp->rel_roffset,
779			    sdp->sd_name));
780			*offset = TLS_GD_IE_ADD;
781			return (FIX_DONE);
782		}
783		return (FIX_RELOC);
784	}
785
786	/*
787	 * LE reference model
788	 */
789	switch (rtype) {
790	case R_SPARC_TLS_IE_HI22:
791	case R_SPARC_TLS_GD_HI22:
792	case R_SPARC_TLS_LDO_HIX22:
793		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
794		    R_SPARC_TLS_LE_HIX22, arsp->rel_roffset, sdp->sd_name));
795		arsp->rel_rtype = R_SPARC_TLS_LE_HIX22;
796		return (FIX_RELOC);
797
798	case R_SPARC_TLS_LDO_LOX10:
799		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
800		    R_SPARC_TLS_LE_LOX10, arsp->rel_roffset, sdp->sd_name));
801		arsp->rel_rtype = R_SPARC_TLS_LE_LOX10;
802		return (FIX_RELOC);
803
804	case R_SPARC_TLS_IE_LO10:
805	case R_SPARC_TLS_GD_LO10:
806		/*
807		 * Current instruction is:
808		 *
809		 *	or r1, %lo(x), r2
810		 *		or
811		 *	add r1, %lo(x), r2
812		 *
813		 *
814		 * Need to udpate this to:
815		 *
816		 *	xor r1, %lox(x), r2
817		 */
818		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
819		    R_SPARC_TLS_LE_LOX10, arsp->rel_roffset, sdp->sd_name));
820		*offset = TLS_GD_LE_XOR |
821		    (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RD));
822		arsp->rel_rtype = R_SPARC_TLS_LE_LOX10;
823		return (FIX_RELOC);
824
825	case R_SPARC_TLS_IE_LD:
826	case R_SPARC_TLS_IE_LDX:
827		/*
828		 * Current instruction:
829		 * 	ld{x}	[r1 + r2], r3
830		 *
831		 * Need to update this to:
832		 *
833		 *	mov	r2, r3   (or  %g0, r2, r3)
834		 */
835		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
836		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
837		*offset = ((*offset) & (FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) |
838		    TLS_IE_LE_OR;
839		return (FIX_DONE);
840
841	case R_SPARC_TLS_LDO_ADD:
842	case R_SPARC_TLS_GD_ADD:
843		/*
844		 * Current instruction is:
845		 *
846		 *	add gptr_reg, r2, r3
847		 *
848		 * Need to updated this to:
849		 *
850		 *	add %g7, r2, r3
851		 */
852		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
853		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
854		*offset = *offset & (~FM3_REG_MSK_RS1);
855		*offset = *offset | (REG_G7 << 14);
856		return (FIX_DONE);
857
858	case R_SPARC_TLS_LDM_CALL:
859		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
860		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
861		*offset = TLS_LD_LE_CLRO0;
862		return (FIX_DONE);
863
864	case R_SPARC_TLS_LDM_HI22:
865	case R_SPARC_TLS_LDM_LO10:
866	case R_SPARC_TLS_LDM_ADD:
867	case R_SPARC_TLS_IE_ADD:
868	case R_SPARC_TLS_GD_CALL:
869		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
870		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
871		*offset = M_NOP;
872		return (FIX_DONE);
873	}
874	return (FIX_RELOC);
875}
876
877#define	GOTOP_ADDINST	0x80000000	/* add %g0, %g0, %g0 */
878
879static Fixupret
880gotop_fixups(Ofl_desc *ofl, Rel_desc *arsp)
881{
882	Sym_desc	*sdp = arsp->rel_sym;
883	Word		rtype = arsp->rel_rtype;
884	uint_t		*offset;
885	const char	*ifl_name;
886
887	switch (rtype) {
888	case R_SPARC_GOTDATA_OP_HIX22:
889		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
890		    R_SPARC_GOTDATA_HIX22, arsp->rel_roffset, sdp->sd_name));
891		arsp->rel_rtype = R_SPARC_GOTDATA_HIX22;
892		return (FIX_RELOC);
893
894	case R_SPARC_GOTDATA_OP_LOX10:
895		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
896		    R_SPARC_GOTDATA_LOX10, arsp->rel_roffset, sdp->sd_name));
897		arsp->rel_rtype = R_SPARC_GOTDATA_LOX10;
898		return (FIX_RELOC);
899
900	case R_SPARC_GOTDATA_OP:
901		/*
902		 * Current instruction:
903		 * 	ld{x}	[r1 + r2], r3
904		 *
905		 * Need to update this to:
906		 *
907		 *	add	r1, r2, r3
908		 */
909		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
910		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
911		offset = (uint_t *)(uintptr_t)(arsp->rel_roffset +
912		    _elf_getxoff(arsp->rel_isdesc->is_indata) +
913		    (uintptr_t)arsp->rel_osdesc->os_outdata->d_buf);
914
915		*offset = ((*offset) & (FM3_REG_MSK_RS1 |
916		    FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) | GOTOP_ADDINST;
917		return (FIX_DONE);
918	}
919	/*
920	 * We should not get here
921	 */
922	if (arsp->rel_isdesc->is_file)
923		ifl_name = arsp->rel_isdesc->is_file->ifl_name;
924	else
925		ifl_name = MSG_INTL(MSG_STR_NULL);
926
927	eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTFIX),
928	    conv_reloc_SPARC_type(arsp->rel_rtype, 0),
929	    ifl_name, demangle(arsp->rel_sname));
930
931	assert(0);
932	return (FIX_ERROR);
933}
934
935uintptr_t
936ld_do_activerelocs(Ofl_desc *ofl)
937{
938	Rel_desc	*arsp;
939	Rel_cache	*rcp;
940	Listnode	*lnp;
941	uintptr_t	return_code = 1;
942	Word		flags = ofl->ofl_flags;
943	Word		dtflags1 = ofl->ofl_dtflags_1;
944
945	if (ofl->ofl_actrels.head)
946		DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
947
948	/*
949	 * Process active relocations.
950	 */
951	for (LIST_TRAVERSE(&ofl->ofl_actrels, lnp, rcp)) {
952		/* LINTED */
953		for (arsp = (Rel_desc *)(rcp + 1);
954		    arsp < rcp->rc_free; arsp++) {
955			uchar_t		*addr;
956			Xword		value;
957			Sym_desc	*sdp;
958			const char	*ifl_name;
959			Xword		refaddr;
960
961			/*
962			 * If the section this relocation is against has been
963			 * discarded (-zignore), then discard (skip) the
964			 * relocation itself.
965			 */
966			if ((arsp->rel_isdesc->is_flags & FLG_IS_DISCARD) &&
967			    ((arsp->rel_flags &
968			    (FLG_REL_GOT | FLG_REL_BSS |
969			    FLG_REL_PLT | FLG_REL_NOINFO)) == 0)) {
970				DBG_CALL(Dbg_reloc_discard(ofl->ofl_lml,
971				    M_MACH, arsp));
972				continue;
973			}
974
975			/*
976			 * Perform any required TLS fixups.
977			 */
978			if (arsp->rel_flags & FLG_REL_TLSFIX) {
979				Fixupret	ret;
980
981				if ((ret = tls_fixups(ofl, arsp)) == FIX_ERROR)
982					return (S_ERROR);
983				if (ret == FIX_DONE)
984					continue;
985			}
986
987			/*
988			 * Perform any required GOTOP fixups.
989			 */
990			if (arsp->rel_flags & FLG_REL_GOTFIX) {
991				Fixupret	ret;
992
993				if ((ret =
994				    gotop_fixups(ofl, arsp)) == FIX_ERROR)
995					return (S_ERROR);
996				if (ret == FIX_DONE)
997					continue;
998			}
999
1000			/*
1001			 * If this is a relocation against the move table, or
1002			 * expanded move table, adjust the relocation entries.
1003			 */
1004			if (arsp->rel_move)
1005				ld_adj_movereloc(ofl, arsp);
1006
1007			sdp = arsp->rel_sym;
1008			refaddr = arsp->rel_roffset +
1009			    (Off)_elf_getxoff(arsp->rel_isdesc->is_indata);
1010
1011			if ((arsp->rel_flags & FLG_REL_CLVAL) ||
1012			    (arsp->rel_flags & FLG_REL_GOTCL))
1013				value = 0;
1014			else if (ELF_ST_TYPE(sdp->sd_sym->st_info) ==
1015			    STT_SECTION) {
1016				Sym_desc	*sym;
1017
1018				/*
1019				 * The value for a symbol pointing to a SECTION
1020				 * is based off of that sections position.
1021				 */
1022				if ((sdp->sd_isc->is_flags & FLG_IS_RELUPD) &&
1023				    (sym = ld_am_I_partial(arsp,
1024				    arsp->rel_roffset))) {
1025					/*
1026					 * If the symbol is moved,
1027					 * adjust the value
1028					 */
1029					value = _elf_getxoff(
1030					    sym->sd_isc->is_indata);
1031					if (sym->sd_isc->is_shdr->sh_flags &
1032					    SHF_ALLOC)
1033						value += sym->sd_isc->
1034						    is_osdesc->os_shdr->sh_addr;
1035				} else {
1036					value = _elf_getxoff(
1037					    sdp->sd_isc->is_indata);
1038					if (sdp->sd_isc->is_shdr->sh_flags &
1039					    SHF_ALLOC)
1040						value += sdp->sd_isc->
1041						    is_osdesc->os_shdr->sh_addr;
1042				}
1043
1044				if (sdp->sd_isc->is_shdr->sh_flags & SHF_TLS)
1045					value -= ofl->ofl_tlsphdr->p_vaddr;
1046			} else {
1047				/*
1048				 * Else the value is the symbols value.
1049				 */
1050				value = sdp->sd_sym->st_value;
1051			}
1052
1053			/*
1054			 * Relocation against the GLOBAL_OFFSET_TABLE.
1055			 */
1056			if (arsp->rel_flags & FLG_REL_GOT)
1057				arsp->rel_osdesc = ofl->ofl_osgot;
1058
1059			/*
1060			 * If loadable and not producing a relocatable object
1061			 * add the sections virtual address to the reference
1062			 * address.
1063			 */
1064			if ((arsp->rel_flags & FLG_REL_LOAD) &&
1065			    ((flags & FLG_OF_RELOBJ) == 0))
1066				refaddr += arsp->rel_isdesc->is_osdesc->
1067				    os_shdr->sh_addr;
1068
1069			/*
1070			 * If this entry has a PLT assigned to it, it's
1071			 * value is actually the address of the PLT (and
1072			 * not the address of the function).
1073			 */
1074			if (IS_PLT(arsp->rel_rtype)) {
1075				if (sdp->sd_aux && sdp->sd_aux->sa_PLTndx)
1076					value = ld_calc_plt_addr(sdp, ofl);
1077			}
1078
1079			/*
1080			 * Add relocations addend to value.  Add extra
1081			 * relocation addend if needed.
1082			 */
1083			value += arsp->rel_raddend;
1084			if (IS_EXTOFFSET(arsp->rel_rtype))
1085				value += arsp->rel_typedata;
1086
1087			/*
1088			 * Determine whether the value needs further adjustment.
1089			 * Filter through the attributes of the relocation to
1090			 * determine what adjustment is required.  Note, many
1091			 * of the following cases are only applicable when a
1092			 * .got is present.  As a .got is not generated when a
1093			 * relocatable object is being built, any adjustments
1094			 * that require a .got need to be skipped.
1095			 */
1096			if ((arsp->rel_flags & FLG_REL_GOT) &&
1097			    ((flags & FLG_OF_RELOBJ) == 0)) {
1098				Xword		R1addr;
1099				uintptr_t	R2addr;
1100				Sword		gotndx;
1101				Gotndx		*gnp;
1102				Gotref		gref;
1103
1104				/*
1105				 * Clear the GOT table entry, on SPARC we clear
1106				 * the entry and the 'value' if needed is stored
1107				 * in an output relocations addend.
1108				 *
1109				 * Calculate offset into GOT at which to apply
1110				 * the relocation.
1111				 */
1112				if (arsp->rel_flags & FLG_REL_DTLS)
1113					gref = GOT_REF_TLSGD;
1114				else if (arsp->rel_flags & FLG_REL_MTLS)
1115					gref = GOT_REF_TLSLD;
1116				else if (arsp->rel_flags & FLG_REL_STLS)
1117					gref = GOT_REF_TLSIE;
1118				else
1119					gref = GOT_REF_GENERIC;
1120
1121				gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), gref,
1122				    ofl, arsp);
1123				assert(gnp);
1124
1125				if (arsp->rel_rtype == M_R_DTPOFF)
1126					gotndx = gnp->gn_gotndx + 1;
1127				else
1128					gotndx = gnp->gn_gotndx;
1129
1130				/* LINTED */
1131				R1addr = (Xword)((-neggotoffset *
1132				    M_GOT_ENTSIZE) + (gotndx * M_GOT_ENTSIZE));
1133
1134				/*
1135				 * Add the GOTs data's offset.
1136				 */
1137				R2addr = R1addr + (uintptr_t)
1138				    arsp->rel_osdesc->os_outdata->d_buf;
1139
1140				DBG_CALL(Dbg_reloc_doact(ofl->ofl_lml,
1141				    ELF_DBG_LD, M_MACH, SHT_RELA,
1142				    arsp->rel_rtype, R1addr, value,
1143				    arsp->rel_sname, arsp->rel_osdesc));
1144
1145				/*
1146				 * And do it.
1147				 */
1148				*(Xword *)R2addr = value;
1149				continue;
1150
1151			} else if (IS_GOT_BASED(arsp->rel_rtype) &&
1152			    ((flags & FLG_OF_RELOBJ) == 0)) {
1153				value -= (ofl->ofl_osgot->os_shdr->sh_addr +
1154					(-neggotoffset * M_GOT_ENTSIZE));
1155
1156			} else if (IS_PC_RELATIVE(arsp->rel_rtype)) {
1157				value -= refaddr;
1158
1159			} else if (IS_TLS_INS(arsp->rel_rtype) &&
1160			    IS_GOT_RELATIVE(arsp->rel_rtype) &&
1161			    ((flags & FLG_OF_RELOBJ) == 0)) {
1162				Gotndx	*gnp;
1163				Gotref	gref;
1164
1165				if (arsp->rel_flags & FLG_REL_STLS)
1166					gref = GOT_REF_TLSIE;
1167				else if (arsp->rel_flags & FLG_REL_DTLS)
1168					gref = GOT_REF_TLSGD;
1169				else if (arsp->rel_flags & FLG_REL_MTLS)
1170					gref = GOT_REF_TLSLD;
1171
1172				gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), gref,
1173				    ofl, arsp);
1174				assert(gnp);
1175
1176				value = gnp->gn_gotndx * M_GOT_ENTSIZE;
1177
1178			} else if (IS_GOT_RELATIVE(arsp->rel_rtype) &&
1179			    ((flags & FLG_OF_RELOBJ) == 0)) {
1180				Gotndx	*gnp;
1181
1182				gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
1183				    GOT_REF_GENERIC, ofl, arsp);
1184				assert(gnp);
1185
1186				value = gnp->gn_gotndx * M_GOT_ENTSIZE;
1187
1188			} else if ((arsp->rel_flags & FLG_REL_STLS) &&
1189			    ((flags & FLG_OF_RELOBJ) == 0)) {
1190				Xword	tlsstatsize;
1191
1192				/*
1193				 * This is the LE TLS
1194				 * reference model.  Static offset
1195				 * is hard-coded, and negated so that
1196				 * it can be added to the thread pointer (%g7)
1197				 */
1198				tlsstatsize = S_ROUND(ofl->
1199				    ofl_tlsphdr->p_memsz, M_TLSSTATALIGN);
1200				value = -(tlsstatsize - value);
1201			}
1202
1203			if (arsp->rel_isdesc->is_file)
1204				ifl_name = arsp->rel_isdesc->is_file->ifl_name;
1205			else
1206				ifl_name = MSG_INTL(MSG_STR_NULL);
1207
1208			/*
1209			 * Make sure we have data to relocate.  Compiler and
1210			 * assembler developers have been known to generate
1211			 * relocations against invalid sections (normally .bss),
1212			 * so for their benefit give them sufficient information
1213			 * to help analyze the problem.  End users should never
1214			 * see this.
1215			 */
1216			if (arsp->rel_isdesc->is_indata->d_buf == 0) {
1217				eprintf(ofl->ofl_lml, ERR_FATAL,
1218				    MSG_INTL(MSG_REL_EMPTYSEC),
1219				    conv_reloc_SPARC_type(arsp->rel_rtype, 0),
1220				    ifl_name, demangle(arsp->rel_sname),
1221				    arsp->rel_isdesc->is_name);
1222				return (S_ERROR);
1223			}
1224
1225			/*
1226			 * Get the address of the data item we need to modify.
1227			 */
1228			addr = (uchar_t *)((uintptr_t)arsp->rel_roffset +
1229			    (uintptr_t)_elf_getxoff(arsp->rel_isdesc->
1230			    is_indata));
1231
1232			/*LINTED*/
1233			DBG_CALL(Dbg_reloc_doact(ofl->ofl_lml, ELF_DBG_LD,
1234			    M_MACH, SHT_RELA, arsp->rel_rtype, EC_NATPTR(addr),
1235			    value, arsp->rel_sname, arsp->rel_osdesc));
1236			addr += (uintptr_t)arsp->rel_osdesc->os_outdata->d_buf;
1237
1238			if ((((uintptr_t)addr - (uintptr_t)ofl->ofl_nehdr) >
1239			    ofl->ofl_size) || (arsp->rel_roffset >
1240			    arsp->rel_osdesc->os_shdr->sh_size)) {
1241				int	class;
1242
1243				if (((uintptr_t)addr -
1244				    (uintptr_t)ofl->ofl_nehdr) > ofl->ofl_size)
1245					class = ERR_FATAL;
1246				else
1247					class = ERR_WARNING;
1248
1249				eprintf(ofl->ofl_lml, class,
1250				    MSG_INTL(MSG_REL_INVALOFFSET),
1251				    conv_reloc_SPARC_type(arsp->rel_rtype, 0),
1252				    ifl_name, arsp->rel_isdesc->is_name,
1253				    demangle(arsp->rel_sname),
1254				    EC_ADDR((uintptr_t)addr -
1255				    (uintptr_t)ofl->ofl_nehdr));
1256
1257				if (class == ERR_FATAL) {
1258					return_code = S_ERROR;
1259					continue;
1260				}
1261			}
1262
1263			/*
1264			 * If '-z noreloc' is specified - skip the do_reloc
1265			 * stage.
1266			 */
1267			if ((flags & FLG_OF_RELOBJ) ||
1268			    !(dtflags1 & DF_1_NORELOC)) {
1269				if (do_reloc((uchar_t)arsp->rel_rtype, addr,
1270				    &value, arsp->rel_sname, ifl_name,
1271				    ofl->ofl_lml) == 0)
1272					return_code = S_ERROR;
1273			}
1274		}
1275	}
1276	return (return_code);
1277}
1278
1279uintptr_t
1280ld_add_outrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl)
1281{
1282	Rel_desc	*orsp;
1283	Rel_cache	*rcp;
1284	Sym_desc	*sdp = rsp->rel_sym;
1285
1286	/*
1287	 * Static executables *do not* want any relocations against them.
1288	 * Since our engine still creates relocations against a WEAK UNDEFINED
1289	 * symbol in a static executable, it's best to disable them here
1290	 * instead of through out the relocation code.
1291	 */
1292	if ((ofl->ofl_flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
1293	    (FLG_OF_STATIC | FLG_OF_EXEC))
1294		return (1);
1295
1296	/*
1297	 * Certain relocations do not make sense in a 64bit shared object,
1298	 * if building a shared object do a sanity check on the output
1299	 * relocations being created.
1300	 */
1301	if (ofl->ofl_flags & FLG_OF_SHAROBJ) {
1302		Word	rtype = rsp->rel_rtype;
1303		/*
1304		 * Because the R_SPARC_HIPLT22 & R_SPARC_LOPLT10 relocations
1305		 * are not relative they make no sense to create in a shared
1306		 * object - so emit the proper error message if that occurs.
1307		 */
1308		if ((rtype == R_SPARC_HIPLT22) ||
1309		    (rtype == R_SPARC_LOPLT10)) {
1310			eprintf(ofl->ofl_lml, ERR_FATAL,
1311			    MSG_INTL(MSG_REL_UNRELREL),
1312			    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1313			    rsp->rel_isdesc->is_file->ifl_name,
1314			    demangle(rsp->rel_sname));
1315			return (S_ERROR);
1316		}
1317#if	defined(_ELF64)
1318		/*
1319		 * Each of the following relocations requires that the
1320		 * object being built be loaded in either the upper 32 or
1321		 * 44 bit range of memory.  Since shared libraries traditionally
1322		 * are loaded in the lower range of memory - this isn't going
1323		 * to work.
1324		 */
1325		if ((rtype == R_SPARC_H44) || (rtype == R_SPARC_M44) ||
1326		    (rtype == R_SPARC_L44)) {
1327			eprintf(ofl->ofl_lml, ERR_FATAL,
1328			    MSG_INTL(MSG_REL_SHOBJABS44),
1329			    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1330			    rsp->rel_isdesc->is_file->ifl_name,
1331			    demangle(rsp->rel_sname));
1332			return (S_ERROR);
1333		}
1334#endif
1335	}
1336
1337	/*
1338	 * If no relocation cache structures are available allocate
1339	 * a new one and link it into the cache list.
1340	 */
1341	if ((ofl->ofl_outrels.tail == 0) ||
1342	    ((rcp = (Rel_cache *)ofl->ofl_outrels.tail->data) == 0) ||
1343	    ((orsp = rcp->rc_free) == rcp->rc_end)) {
1344		static size_t	nextsize = 0;
1345		size_t		size;
1346
1347		/*
1348		 * Output relocation numbers can vary considerably between
1349		 * building executables or shared objects (pic vs. non-pic),
1350		 * etc.  But, they typically aren't very large, so for these
1351		 * objects use a standard bucket size.  For building relocatable
1352		 * objects, typically there will be an output relocation for
1353		 * every input relocation.
1354		 */
1355		if (nextsize == 0) {
1356			if (ofl->ofl_flags & FLG_OF_RELOBJ) {
1357				if ((size = ofl->ofl_relocincnt) == 0)
1358					size = REL_LOIDESCNO;
1359				if (size > REL_HOIDESCNO)
1360					nextsize = REL_HOIDESCNO;
1361				else
1362					nextsize = REL_LOIDESCNO;
1363			} else
1364				nextsize = size = REL_HOIDESCNO;
1365		} else
1366			size = nextsize;
1367
1368		size = size * sizeof (Rel_desc);
1369
1370		if (((rcp = libld_malloc(sizeof (Rel_cache) + size)) == 0) ||
1371		    (list_appendc(&ofl->ofl_outrels, rcp) == 0))
1372			return (S_ERROR);
1373
1374		/* LINTED */
1375		rcp->rc_free = orsp = (Rel_desc *)(rcp + 1);
1376		/* LINTED */
1377		rcp->rc_end = (Rel_desc *)((char *)rcp->rc_free + size);
1378	}
1379
1380
1381	/*
1382	 * If we are adding a output relocation against a section
1383	 * symbol (non-RELATIVE) then mark that section.  These sections
1384	 * will be added to the .dynsym symbol table.
1385	 */
1386	if (sdp && (rsp->rel_rtype != M_R_RELATIVE) &&
1387	    ((flags & FLG_REL_SCNNDX) ||
1388	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))) {
1389
1390		/*
1391		 * If this is a COMMON symbol - no output section
1392		 * exists yet - (it's created as part of sym_validate()).
1393		 * So - we mark here that when it's created it should
1394		 * be tagged with the FLG_OS_OUTREL flag.
1395		 */
1396		if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1397		    (sdp->sd_sym->st_shndx == SHN_COMMON)) {
1398			if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS)
1399				ofl->ofl_flags1 |= FLG_OF1_BSSOREL;
1400			else
1401				ofl->ofl_flags1 |= FLG_OF1_TLSOREL;
1402		} else {
1403			Os_desc	*osp = sdp->sd_isc->is_osdesc;
1404
1405			if (osp && ((osp->os_flags & FLG_OS_OUTREL) == 0)) {
1406				ofl->ofl_dynshdrcnt++;
1407				osp->os_flags |= FLG_OS_OUTREL;
1408			}
1409		}
1410	}
1411
1412	*orsp = *rsp;
1413	orsp->rel_flags |= flags;
1414
1415	rcp->rc_free++;
1416	ofl->ofl_outrelscnt++;
1417
1418	if (flags & FLG_REL_GOT)
1419		ofl->ofl_relocgotsz += (Xword)sizeof (Rela);
1420	else if (flags & FLG_REL_PLT)
1421		ofl->ofl_relocpltsz += (Xword)sizeof (Rela);
1422	else if (flags & FLG_REL_BSS)
1423		ofl->ofl_relocbsssz += (Xword)sizeof (Rela);
1424	else if (flags & FLG_REL_NOINFO)
1425		ofl->ofl_relocrelsz += (Xword)sizeof (Rela);
1426	else
1427		orsp->rel_osdesc->os_szoutrels += (Xword)sizeof (Rela);
1428
1429	if (orsp->rel_rtype == M_R_RELATIVE)
1430		ofl->ofl_relocrelcnt++;
1431
1432#if	defined(_ELF64)
1433	/*
1434	 * When building a 64-bit object any R_SPARC_WDISP30 relocation is given
1435	 * a plt padding entry, unless we're building a relocatable object
1436	 * (ld -r) or -b is in effect.
1437	 */
1438	if ((orsp->rel_rtype == R_SPARC_WDISP30) &&
1439	    ((ofl->ofl_flags & (FLG_OF_BFLAG | FLG_OF_RELOBJ)) == 0) &&
1440	    ((orsp->rel_sym->sd_flags & FLG_SY_PLTPAD) == 0)) {
1441		ofl->ofl_pltpad++;
1442		orsp->rel_sym->sd_flags |= FLG_SY_PLTPAD;
1443	}
1444#endif
1445	/*
1446	 * We don't perform sorting on PLT relocations because
1447	 * they have already been assigned a PLT index and if we
1448	 * were to sort them we would have to re-assign the plt indexes.
1449	 */
1450	if (!(flags & FLG_REL_PLT))
1451		ofl->ofl_reloccnt++;
1452
1453	/*
1454	 * Insure a GLOBAL_OFFSET_TABLE is generated if required.
1455	 */
1456	if (IS_GOT_REQUIRED(orsp->rel_rtype))
1457		ofl->ofl_flags |= FLG_OF_BLDGOT;
1458
1459	/*
1460	 * Identify and possibly warn of a displacement relocation.
1461	 */
1462	if (orsp->rel_flags & FLG_REL_DISP) {
1463		ofl->ofl_dtflags_1 |= DF_1_DISPRELPND;
1464
1465		if (ofl->ofl_flags & FLG_OF_VERBOSE)
1466			ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL4), orsp, ofl);
1467	}
1468	DBG_CALL(Dbg_reloc_ors_entry(ofl->ofl_lml, ELF_DBG_LD, SHT_RELA,
1469	    M_MACH, orsp));
1470	return (1);
1471}
1472
1473/*
1474 * Process relocation against a register symbol.  Note, of -z muldefs is in
1475 * effect there may have been multiple register definitions, which would have
1476 * been processed as non-fatal, with the first definition winning.  But, we
1477 * will also process multiple relocations for these multiple definitions.  In
1478 * this case we must only preserve the relocation for the definition that was
1479 * kept.  The sad part is that register relocations don't typically specify
1480 * the register symbol with which they are associated, so we might have to
1481 * search the input files global symbols to determine if this relocation is
1482 * appropriate.
1483 */
1484uintptr_t
1485ld_reloc_register(Rel_desc * rsp, Is_desc * isp, Ofl_desc * ofl)
1486{
1487	if (ofl->ofl_flags & FLG_OF_MULDEFS) {
1488		Ifl_desc *	ifl = isp->is_file;
1489		Sym_desc *	sdp = rsp->rel_sym;
1490
1491		if (sdp == 0) {
1492			Xword		offset = rsp->rel_roffset;
1493			Word		ndx;
1494
1495			for (ndx = ifl->ifl_locscnt;
1496			    ndx < ifl->ifl_symscnt; ndx++) {
1497				if (((sdp = ifl->ifl_oldndx[ndx]) != 0) &&
1498				    (sdp->sd_flags & FLG_SY_REGSYM) &&
1499				    (sdp->sd_sym->st_value == offset))
1500					break;
1501			}
1502		}
1503		if (sdp && (sdp->sd_file != ifl))
1504			return (1);
1505	}
1506	return (ld_add_outrel((rsp->rel_flags | FLG_REL_REG), rsp, ofl));
1507}
1508
1509/*
1510 * process relocation for a LOCAL symbol
1511 */
1512uintptr_t
1513ld_reloc_local(Rel_desc * rsp, Ofl_desc * ofl)
1514{
1515	Word		flags = ofl->ofl_flags;
1516	Sym_desc	*sdp = rsp->rel_sym;
1517	Word		shndx = sdp->sd_sym->st_shndx;
1518
1519	/*
1520	 * if ((shared object) and (not pc relative relocation) and
1521	 *    (not against ABS symbol))
1522	 * then
1523	 *	if (rtype != R_SPARC_32)
1524	 *	then
1525	 *		build relocation against section
1526	 *	else
1527	 *		build R_SPARC_RELATIVE
1528	 *	fi
1529	 * fi
1530	 */
1531	if ((flags & FLG_OF_SHAROBJ) && (rsp->rel_flags & FLG_REL_LOAD) &&
1532	    !(IS_PC_RELATIVE(rsp->rel_rtype)) &&
1533	    !(IS_GOT_BASED(rsp->rel_rtype)) &&
1534	    !(rsp->rel_isdesc != NULL &&
1535	    (rsp->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof)) &&
1536	    (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
1537	    (shndx != SHN_ABS) || (sdp->sd_aux && sdp->sd_aux->sa_symspec))) {
1538		Word	ortype = rsp->rel_rtype;
1539
1540		if ((rsp->rel_rtype != R_SPARC_32) &&
1541		    (rsp->rel_rtype != R_SPARC_PLT32) &&
1542		    (rsp->rel_rtype != R_SPARC_64))
1543			return (ld_add_outrel((FLG_REL_SCNNDX | FLG_REL_ADVAL),
1544			    rsp, ofl));
1545
1546		rsp->rel_rtype = R_SPARC_RELATIVE;
1547		if (ld_add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR)
1548			return (S_ERROR);
1549		rsp->rel_rtype = ortype;
1550		return (1);
1551	}
1552
1553	/*
1554	 * If the relocation is against a 'non-allocatable' section
1555	 * and we can not resolve it now - then give a warning
1556	 * message.
1557	 *
1558	 * We can not resolve the symbol if either:
1559	 *	a) it's undefined
1560	 *	b) it's defined in a shared library and a
1561	 *	   COPY relocation hasn't moved it to the executable
1562	 *
1563	 * Note: because we process all of the relocations against the
1564	 *	text segment before any others - we know whether
1565	 *	or not a copy relocation will be generated before
1566	 *	we get here (see reloc_init()->reloc_segments()).
1567	 */
1568	if (!(rsp->rel_flags & FLG_REL_LOAD) &&
1569	    ((shndx == SHN_UNDEF) ||
1570	    ((sdp->sd_ref == REF_DYN_NEED) &&
1571	    ((sdp->sd_flags & FLG_SY_MVTOCOMM) == 0)))) {
1572		/*
1573		 * If the relocation is against a SHT_SUNW_ANNOTATE
1574		 * section - then silently ignore that the relocation
1575		 * can not be resolved.
1576		 */
1577		if (rsp->rel_osdesc &&
1578		    (rsp->rel_osdesc->os_shdr->sh_type == SHT_SUNW_ANNOTATE))
1579			return (0);
1580		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
1581		    MSG_INTL(MSG_REL_EXTERNSYM),
1582		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1583		    rsp->rel_isdesc->is_file->ifl_name,
1584		    demangle(rsp->rel_sname), rsp->rel_osdesc->os_name);
1585		return (1);
1586	}
1587
1588	/*
1589	 * Perform relocation.
1590	 */
1591	return (ld_add_actrel(NULL, rsp, ofl));
1592}
1593
1594uintptr_t
1595ld_reloc_GOTOP(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
1596{
1597	Word	rtype = rsp->rel_rtype;
1598
1599	if (!local) {
1600		/*
1601		 * When binding to a external symbol, no fixups are required
1602		 * and the GOTDATA_OP relocation can be ignored.
1603		 */
1604		if (rtype == R_SPARC_GOTDATA_OP)
1605			return (1);
1606		return (ld_reloc_GOT_relative(local, rsp, ofl));
1607	}
1608
1609	/*
1610	 * When binding to a local symbol the relocations can be transitioned:
1611	 *
1612	 *	R_*_GOTDATA_OP_HIX22 -> R_*_GOTDATA_HIX22
1613	 *	R_*_GOTDATA_OP_LOX10 -> R_*_GOTDATA_LOX10
1614	 *	R_*_GOTDATA_OP ->	instruction fixup
1615	 */
1616	return (ld_add_actrel(FLG_REL_GOTFIX, rsp, ofl));
1617}
1618
1619uintptr_t
1620ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
1621{
1622	Word		rtype = rsp->rel_rtype;
1623	Sym_desc	*sdp = rsp->rel_sym;
1624	Word		flags = ofl->ofl_flags;
1625	Gotndx		*gnp;
1626
1627	/*
1628	 * If we're building an executable - use either the IE or LE access
1629	 * model.  If we're building a shared object process any IE model.
1630	 */
1631	if ((flags & FLG_OF_EXEC) || (IS_TLS_IE(rtype))) {
1632		/*
1633		 * Set the DF_STATIC_TLS flag.
1634		 */
1635		ofl->ofl_dtflags |= DF_STATIC_TLS;
1636
1637		if (!local || ((flags & FLG_OF_EXEC) == 0)) {
1638			/*
1639			 * When processing static TLS - these relocations
1640			 * can be ignored.
1641			 */
1642			if ((rtype == R_SPARC_TLS_IE_LD) ||
1643			    (rtype == R_SPARC_TLS_IE_LDX) ||
1644			    (rtype == R_SPARC_TLS_IE_ADD))
1645				return (1);
1646
1647			/*
1648			 * Assign a GOT entry for IE static TLS references.
1649			 */
1650			if (((rtype == R_SPARC_TLS_GD_HI22) ||
1651			    (rtype == R_SPARC_TLS_GD_LO10) ||
1652			    (rtype == R_SPARC_TLS_IE_HI22) ||
1653			    (rtype == R_SPARC_TLS_IE_LO10)) &&
1654			    ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
1655			    GOT_REF_TLSIE, ofl, rsp)) == 0)) {
1656
1657				if (ld_assign_got_TLS(local, rsp, ofl, sdp,
1658				    gnp, GOT_REF_TLSIE, FLG_REL_STLS,
1659				    rtype, M_R_TPOFF, 0) == S_ERROR)
1660					return (S_ERROR);
1661			}
1662
1663			/*
1664			 * IE access model.
1665			 */
1666			if (IS_TLS_IE(rtype))
1667				return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
1668
1669			/*
1670			 * Fixups are required for other executable models.
1671			 */
1672			return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
1673			    rsp, ofl));
1674		}
1675
1676		/*
1677		 * LE access model.
1678		 */
1679		if (IS_TLS_LE(rtype))
1680			return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
1681
1682		/*
1683		 * When processing static TLS - these relocations can be
1684		 * ignored.
1685		 */
1686		if (rtype == R_SPARC_TLS_IE_ADD)
1687			return (1);
1688
1689		return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
1690		    rsp, ofl));
1691	}
1692
1693	/*
1694	 * Building a shared object.
1695	 *
1696	 * For dynamic TLS references, ADD relocations are ignored.
1697	 */
1698	if ((rtype == R_SPARC_TLS_GD_ADD) || (rtype == R_SPARC_TLS_LDM_ADD) ||
1699	    (rtype == R_SPARC_TLS_LDO_ADD))
1700		return (1);
1701
1702	/*
1703	 * Assign a GOT entry for a dynamic TLS reference.
1704	 */
1705	if (((rtype == R_SPARC_TLS_LDM_HI22) ||
1706	    (rtype == R_SPARC_TLS_LDM_LO10)) &&
1707	    ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSLD,
1708	    ofl, rsp)) == 0)) {
1709
1710		if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSLD,
1711		    FLG_REL_MTLS, rtype, M_R_DTPMOD, 0) == S_ERROR)
1712			return (S_ERROR);
1713
1714	} else if (((rtype == R_SPARC_TLS_GD_HI22) ||
1715	    (rtype == R_SPARC_TLS_GD_LO10)) &&
1716	    ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_TLSGD,
1717	    ofl, rsp)) == 0)) {
1718
1719		if (ld_assign_got_TLS(local, rsp, ofl, sdp, gnp, GOT_REF_TLSGD,
1720		    FLG_REL_DTLS, rtype, M_R_DTPMOD, M_R_DTPOFF) == S_ERROR)
1721			return (S_ERROR);
1722	}
1723
1724	/*
1725	 * For GD/LD TLS reference - TLS_{GD,LD}_CALL, this will eventually
1726	 * cause a call to __tls_get_addr().  Convert this relocation to that
1727	 * symbol now, and prepare for the PLT magic.
1728	 */
1729	if ((rtype == R_SPARC_TLS_GD_CALL) || (rtype == R_SPARC_TLS_LDM_CALL)) {
1730		Sym_desc *	tlsgetsym;
1731
1732		if ((tlsgetsym = ld_sym_add_u(MSG_ORIG(MSG_SYM_TLSGETADDR_U),
1733		    ofl)) == (Sym_desc *)S_ERROR)
1734			return (S_ERROR);
1735
1736		rsp->rel_sym = tlsgetsym;
1737		rsp->rel_sname = tlsgetsym->sd_name;
1738		rsp->rel_rtype = R_SPARC_WPLT30;
1739
1740		if (ld_reloc_plt(rsp, ofl) == S_ERROR)
1741			return (S_ERROR);
1742
1743		rsp->rel_sym = sdp;
1744		rsp->rel_sname = sdp->sd_name;
1745		rsp->rel_rtype = rtype;
1746		return (1);
1747	}
1748
1749	if (IS_TLS_LD(rtype))
1750		return (ld_add_actrel(FLG_REL_MTLS, rsp, ofl));
1751
1752	return (ld_add_actrel(FLG_REL_DTLS, rsp, ofl));
1753}
1754
1755/*
1756 * ld_allocate_got: if a GOT is to be made, after the section is built this
1757 * function is called to allocate all the GOT slots.  The allocation is
1758 * deferred until after all GOTs have been counted and sorted according
1759 * to their size, for only then will we know how to allocate them on
1760 * a processor like SPARC which has different models for addressing the
1761 * GOT.  SPARC has two: small and large, small uses a signed 13-bit offset
1762 * into the GOT, whereas large uses an unsigned 32-bit offset.
1763 */
1764static	Sword small_index;	/* starting index for small GOT entries */
1765static	Sword large_index;	/* starting index for large GOT entries */
1766
1767uintptr_t
1768ld_assign_got(Ofl_desc *ofl, Sym_desc * sdp)
1769{
1770	Listnode *	lnp;
1771	Gotndx *	gnp;
1772
1773	for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp, gnp)) {
1774		uint_t	gotents;
1775		Gotref	gref;
1776		gref = gnp->gn_gotref;
1777		if ((gref == GOT_REF_TLSGD) || (gref == GOT_REF_TLSLD))
1778			gotents = 2;
1779		else
1780			gotents = 1;
1781
1782		switch (gnp->gn_gotndx) {
1783		case M_GOT_SMALL:
1784			gnp->gn_gotndx = small_index;
1785			small_index += gotents;
1786			if (small_index == 0)
1787				small_index = M_GOT_XNumber;
1788			break;
1789		case M_GOT_LARGE:
1790			gnp->gn_gotndx = large_index;
1791			large_index += gotents;
1792			break;
1793		default:
1794			eprintf(ofl->ofl_lml, ERR_FATAL,
1795			    MSG_INTL(MSG_REL_ASSIGNGOT),
1796			    EC_XWORD(gnp->gn_gotndx), demangle(sdp->sd_name));
1797			return (S_ERROR);
1798		}
1799	}
1800	return (1);
1801}
1802
1803/*
1804 * Search the GOT index list for a GOT entry with the proper addend.
1805 */
1806Gotndx *
1807ld_find_gotndx(List * lst, Gotref gref, Ofl_desc * ofl, Rel_desc * rdesc)
1808{
1809	Listnode *	lnp;
1810	Gotndx *	gnp;
1811
1812	if ((gref == GOT_REF_TLSLD) && ofl->ofl_tlsldgotndx)
1813		return (ofl->ofl_tlsldgotndx);
1814
1815	for (LIST_TRAVERSE(lst, lnp, gnp)) {
1816		if ((rdesc->rel_raddend == gnp->gn_addend) &&
1817		    (gref == gnp->gn_gotref))
1818			return (gnp);
1819	}
1820	return ((Gotndx *)0);
1821}
1822
1823Xword
1824ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl)
1825{
1826	Os_desc		*osp = ofl->ofl_osgot;
1827	Sym_desc	*sdp = rdesc->rel_sym;
1828	Xword		gotndx;
1829	Gotref		gref;
1830	Gotndx		*gnp;
1831
1832	if (rdesc->rel_flags & FLG_REL_DTLS)
1833		gref = GOT_REF_TLSGD;
1834	else if (rdesc->rel_flags & FLG_REL_MTLS)
1835		gref = GOT_REF_TLSLD;
1836	else if (rdesc->rel_flags & FLG_REL_STLS)
1837		gref = GOT_REF_TLSIE;
1838	else
1839		gref = GOT_REF_GENERIC;
1840
1841	gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), gref, ofl, rdesc);
1842	assert(gnp);
1843
1844	gotndx = (Xword)gnp->gn_gotndx;
1845
1846	if ((rdesc->rel_flags & FLG_REL_DTLS) &&
1847	    (rdesc->rel_rtype == M_R_DTPOFF))
1848		gotndx++;
1849
1850	return ((Xword)((osp->os_shdr->sh_addr) + (gotndx * M_GOT_ENTSIZE) +
1851	    (-neggotoffset * M_GOT_ENTSIZE)));
1852}
1853
1854uintptr_t
1855ld_assign_got_ndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
1856    Rel_desc * rsp, Sym_desc * sdp)
1857{
1858	Xword		raddend;
1859	Gotndx *	gnp, * _gnp;
1860	Listnode *	lnp, * plnp;
1861	uint_t		gotents;
1862
1863	raddend = rsp->rel_raddend;
1864	if (pgnp && (pgnp->gn_addend == raddend) && (pgnp->gn_gotref == gref)) {
1865		/*
1866		 * If an entry for this addend already exists, determine if it
1867		 * should be changed to a SMALL got.
1868		 */
1869		if ((pgnp->gn_gotndx != M_GOT_SMALL) &&
1870		    (rsp->rel_rtype == R_SPARC_GOT13)) {
1871			smlgotcnt++;
1872			pgnp->gn_gotndx = M_GOT_SMALL;
1873			sdp->sd_flags |= FLG_SY_SMGOT;
1874		}
1875		return (1);
1876	}
1877
1878	if ((gref == GOT_REF_TLSGD) || (gref == GOT_REF_TLSLD))
1879		gotents = 2;
1880	else
1881		gotents = 1;
1882
1883	plnp = 0;
1884	for (LIST_TRAVERSE(lst, lnp, _gnp)) {
1885		if (_gnp->gn_addend > raddend)
1886			break;
1887		plnp = lnp;
1888	}
1889
1890	/*
1891	 * Allocate a new entry.
1892	 */
1893	if ((gnp = libld_calloc(sizeof (Gotndx), 1)) == 0)
1894		return (S_ERROR);
1895	gnp->gn_addend = raddend;
1896	gnp->gn_gotref = gref;
1897	ofl->ofl_gotcnt += gotents;
1898
1899	if (rsp->rel_rtype == R_SPARC_GOT13) {
1900		gnp->gn_gotndx = M_GOT_SMALL;
1901		smlgotcnt++;
1902		sdp->sd_flags |= FLG_SY_SMGOT;
1903	} else
1904		gnp->gn_gotndx = M_GOT_LARGE;
1905
1906	if (gref == GOT_REF_TLSLD) {
1907		ofl->ofl_tlsldgotndx = gnp;
1908		return (1);
1909	}
1910
1911	if (plnp == 0) {
1912		/*
1913		 * Insert at head of list
1914		 */
1915		if (list_prependc(lst, (void *)gnp) == 0)
1916			return (S_ERROR);
1917	} else if (_gnp->gn_addend > raddend) {
1918		/*
1919		 * Insert in middle of lest
1920		 */
1921		if (list_insertc(lst, (void *)gnp, plnp) == 0)
1922			return (S_ERROR);
1923	} else {
1924		/*
1925		 * Append to tail of list
1926		 */
1927		if (list_appendc(lst, (void *)gnp) == 0)
1928			return (S_ERROR);
1929	}
1930	return (1);
1931}
1932
1933void
1934ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl)
1935{
1936	sdp->sd_aux->sa_PLTndx = 1 + ofl->ofl_pltcnt++;
1937}
1938
1939
1940uintptr_t
1941ld_allocate_got(Ofl_desc * ofl)
1942{
1943	Sym_desc *	sdp;
1944	Addr		addr;
1945
1946	/*
1947	 * Sanity check -- is this going to fit at all?
1948	 */
1949	if (smlgotcnt >= M_GOT_MAXSMALL) {
1950		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_SMALLGOT),
1951		    EC_WORD(smlgotcnt), M_GOT_MAXSMALL);
1952		return (S_ERROR);
1953	}
1954
1955	/*
1956	 * Set starting offset to be either 0, or a negative index into
1957	 * the GOT based on the number of small symbols we've got.
1958	 */
1959	neggotoffset = ((smlgotcnt > (M_GOT_MAXSMALL / 2)) ?
1960	    -((smlgotcnt - (M_GOT_MAXSMALL / 2))) : 0);
1961
1962	/*
1963	 * Initialize the large and small got offsets (used in assign_got()).
1964	 */
1965	small_index = neggotoffset == 0 ? M_GOT_XNumber : neggotoffset;
1966	large_index = neggotoffset + smlgotcnt;
1967
1968	/*
1969	 * Assign bias to GOT symbols.
1970	 */
1971	addr = -neggotoffset * M_GOT_ENTSIZE;
1972	if (sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL), SYM_NOHASH, 0, ofl))
1973		sdp->sd_sym->st_value = addr;
1974	if (sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl))
1975		sdp->sd_sym->st_value = addr;
1976
1977	if (ofl->ofl_tlsldgotndx) {
1978		ofl->ofl_tlsldgotndx->gn_gotndx = large_index;
1979		large_index += 2;
1980	}
1981	return (1);
1982}
1983
1984/*
1985 * Initializes .got[0] with the _DYNAMIC symbol value.
1986 */
1987uintptr_t
1988ld_fillin_gotplt(Ofl_desc *ofl)
1989{
1990	if (ofl->ofl_osgot) {
1991		Sym_desc	*sdp;
1992
1993		if ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U),
1994		    SYM_NOHASH, 0, ofl)) != NULL) {
1995			uchar_t	*genptr;
1996
1997			genptr = ((uchar_t *)ofl->ofl_osgot->os_outdata->d_buf +
1998			    (-neggotoffset * M_GOT_ENTSIZE) +
1999			    (M_GOT_XDYNAMIC * M_GOT_ENTSIZE));
2000			/* LINTED */
2001			*((Xword *)genptr) = sdp->sd_sym->st_value;
2002		}
2003	}
2004	return (1);
2005}
2006