machrel.sparc.c revision 1976:f0691a145b7e
1139731Simp/*
24Srgrimes * CDDL HEADER START
34Srgrimes *
44Srgrimes * The contents of this file are subject to the terms of the
54Srgrimes * Common Development and Distribution License (the "License").
64Srgrimes * You may not use this file except in compliance with the License.
74Srgrimes *
84Srgrimes * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
94Srgrimes * or http://www.opensolaris.org/os/licensing.
104Srgrimes * See the License for the specific language governing permissions
114Srgrimes * and limitations under the License.
124Srgrimes *
134Srgrimes * When distributing Covered Code, include this CDDL HEADER in each
144Srgrimes * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
154Srgrimes * If applicable, add the following below this CDDL HEADER, with the
164Srgrimes * fields enclosed by brackets "[]" replaced with your own identifying
174Srgrimes * information: Portions Copyright [yyyy] [name of copyright owner]
184Srgrimes *
194Srgrimes * CDDL HEADER END
204Srgrimes */
214Srgrimes
224Srgrimes/*
234Srgrimes *	Copyright (c) 1988 AT&T
244Srgrimes *	  All Rights Reserved
254Srgrimes *
264Srgrimes * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
274Srgrimes * Use is subject to license terms.
284Srgrimes */
29621Srgrimes#pragma ident	"%Z%%M%	%I%	%E% SMI"
3050477Speter
314Srgrimes#include	<string.h>
324Srgrimes#include	<stdio.h>
33719Swollman#include	<sys/elf_SPARC.h>
34719Swollman#include	<debug.h>
35719Swollman#include	<reloc.h>
36128629Sdas#include	"msg.h"
37128629Sdas#include	"_libld.h"
38132383Sdas
39132383Sdas/*
40132383Sdas * Local Variable Definitions
41132383Sdas */
424Srgrimesstatic Sword neggotoffset = 0;		/* off. of GOT table from GOT symbol */
43132383Sdasstatic Sword smlgotcnt = M_GOT_XNumber;	/* no. of small GOT symbols */
44128629Sdas
45235939SobrienWord
46175398Sbdeld_init_rel(Rel_desc *reld, void *reloc)
47232491Stijl{
48232491Stijl	Rela *	rela = (Rela *)reloc;
49232491Stijl
50110566Smike	/* LINTED */
51128629Sdas	reld->rel_rtype = (Word)ELF_R_TYPE(rela->r_info);
524Srgrimes	reld->rel_roffset = rela->r_offset;
534Srgrimes	reld->rel_raddend = rela->r_addend;
544Srgrimes	reld->rel_typedata = (Word)ELF_R_TYPE_DATA(rela->r_info);
554Srgrimes
5680Snate	reld->rel_flags |= FLG_REL_RELA;
574Srgrimes
5880Snate	return ((Word)ELF_R_SYM(rela->r_info));
594Srgrimes}
604Srgrimes
614Srgrimesvoid
62230475Sdasld_mach_eflags(Ehdr *ehdr, Ofl_desc *ofl)
63230475Sdas{
64230475Sdas	Word		eflags = ofl->ofl_dehdr->e_flags;
65230475Sdas	Word		memopt1, memopt2;
66230475Sdas	static int	firstpass;
674Srgrimes
684Srgrimes	/*
694Srgrimes	 * If a *PLUS relocatable is included, the output object is type *PLUS.
704Srgrimes	 */
7180Snate	if ((ehdr->e_machine == EM_SPARC32PLUS) &&
7279Snate	    (ehdr->e_flags & EF_SPARC_32PLUS))
7380Snate		ofl->ofl_dehdr->e_machine = EM_SPARC32PLUS;
744Srgrimes
7579Snate	/*
764Srgrimes	 * On the first pass, we don't yet have a memory model to compare
77230475Sdas	 * against, therefore the initial file becomes our baseline.  Subsequent
78230475Sdas	 * passes will do the comparison described below.
79230475Sdas	 */
80230475Sdas	if (firstpass == 0) {
81230475Sdas		ofl->ofl_dehdr->e_flags |= ehdr->e_flags;
824Srgrimes		firstpass++;
83105910Simp		return;
84105910Simp	}
85105910Simp
86105910Simp	/*
87105910Simp	 * Determine which memory model to mark the binary with.  The options
88105910Simp	 * are (most restrictive to least):
89105910Simp	 *
90105910Simp	 *	EF_SPARCV9_TSO		0x0 	Total Store Order
91105910Simp	 *	EF_SPARCV9_PSO		0x1	Partial Store Order
92230475Sdas	 *	EF_SPARCV9_RMO		0x2	Relaxed Memory Order
93230475Sdas	 *
94230475Sdas	 * Mark the binary with the most restrictive option encountered from a
95230475Sdas	 * relocatable object included in the link.
96230475Sdas	 */
97230475Sdas	eflags |= (ehdr->e_flags & ~EF_SPARCV9_MM);
98719Swollman	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	 * addend field for R_SPARC_TLS_DTPMOD32 &&
680	 * R_SPARC_TLS_DTPMOD64 mean nothing.  The addend
681	 * is propogated in the corresponding R_SPARC_TLS_DTPOFF*
682	 * relocations.
683	 */
684	if (orsp->rel_rtype == M_R_DTPMOD) {
685		raddend = 0;
686	}
687
688	relbits = (char *)relosp->os_outdata->d_buf;
689
690	rea.r_info = ELF_R_INFO(ndx, ELF_R_TYPE_INFO(orsp->rel_typedata,
691			orsp->rel_rtype));
692	rea.r_offset = roffset;
693	rea.r_addend = raddend;
694	DBG_CALL(Dbg_reloc_out(ofl, ELF_DBG_LD, SHT_RELA, &rea, relosp->os_name,
695	    orsp->rel_sname));
696
697	/*
698	 * Assert we haven't walked off the end of our relocation table.
699	 */
700	assert(relosp->os_szoutrels <= relosp->os_shdr->sh_size);
701
702	(void) memcpy((relbits + relosp->os_szoutrels),
703	    (char *)&rea, sizeof (Rela));
704	relosp->os_szoutrels += (Xword)sizeof (Rela);
705
706	/*
707	 * Determine if this relocation is against a non-writable, allocatable
708	 * section.  If so we may need to provide a text relocation diagnostic.
709	 */
710	ld_reloc_remain_entry(orsp, osp, ofl);
711	return (1);
712}
713
714
715/*
716 * Sparc Instructions for TLS processing
717 */
718#if	defined(_ELF64)
719#define	TLS_GD_IE_LD	0xd0580000	/* ldx [%g0 + %g0], %o0 */
720#else
721#define	TLS_GD_IE_LD	0xd0000000	/* ld [%g0 + %g0], %o0 */
722#endif
723#define	TLS_GD_IE_ADD	0x9001c008	/* add %g7, %o0, %o0 */
724
725#define	TLS_GD_LE_XOR	0x80182000	/* xor %g0, 0, %g0 */
726#define	TLS_IE_LE_OR	0x80100000	/* or %g0, %o0, %o1 */
727					/*  synthetic: mov %g0, %g0 */
728
729#define	TLS_LD_LE_CLRO0	0x90100000	/* clr	%o0 */
730
731#define	FM3_REG_MSK_RD	(0x1f << 25)	/* Formate (3) rd register mask */
732					/*	bits 25->29 */
733#define	FM3_REG_MSK_RS1	(0x1f << 14)	/* Formate (3) rs1 register mask */
734					/*	bits 14->18 */
735#define	FM3_REG_MSK_RS2	0x1f		/* Formate (3) rs2 register mask */
736					/*	bits 0->4 */
737
738#define	REG_G7		7		/* %g7 register */
739
740static Fixupret
741tls_fixups(Ofl_desc *ofl, Rel_desc *arsp)
742{
743	Sym_desc	*sdp = arsp->rel_sym;
744	Word		rtype = arsp->rel_rtype;
745	uint_t		*offset;
746
747	offset = (uint_t *)((uintptr_t)arsp->rel_roffset +
748		(uintptr_t)_elf_getxoff(arsp->rel_isdesc->is_indata) +
749		(uintptr_t)arsp->rel_osdesc->os_outdata->d_buf);
750
751	if (sdp->sd_ref == REF_DYN_NEED) {
752		/*
753		 * IE reference model
754		 */
755		switch (rtype) {
756		case R_SPARC_TLS_GD_HI22:
757			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
758			    rtype, R_SPARC_TLS_IE_HI22, arsp->rel_roffset,
759			    sdp->sd_name));
760			arsp->rel_rtype = R_SPARC_TLS_IE_HI22;
761			return (FIX_RELOC);
762
763		case R_SPARC_TLS_GD_LO10:
764			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
765			    rtype, R_SPARC_TLS_IE_LO10, arsp->rel_roffset,
766			    sdp->sd_name));
767			arsp->rel_rtype = R_SPARC_TLS_IE_LO10;
768			return (FIX_RELOC);
769
770		case R_SPARC_TLS_GD_ADD:
771			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
772			    rtype, R_SPARC_NONE, arsp->rel_roffset,
773			    sdp->sd_name));
774			*offset = (TLS_GD_IE_LD |
775			    (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RS2)));
776			return (FIX_DONE);
777
778		case R_SPARC_TLS_GD_CALL:
779			DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
780			    rtype, R_SPARC_NONE, arsp->rel_roffset,
781			    sdp->sd_name));
782			*offset = TLS_GD_IE_ADD;
783			return (FIX_DONE);
784		}
785		return (FIX_RELOC);
786	}
787
788	/*
789	 * LE reference model
790	 */
791	switch (rtype) {
792	case R_SPARC_TLS_IE_HI22:
793	case R_SPARC_TLS_GD_HI22:
794	case R_SPARC_TLS_LDO_HIX22:
795		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
796		    R_SPARC_TLS_LE_HIX22, arsp->rel_roffset, sdp->sd_name));
797		arsp->rel_rtype = R_SPARC_TLS_LE_HIX22;
798		return (FIX_RELOC);
799
800	case R_SPARC_TLS_LDO_LOX10:
801		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
802		    R_SPARC_TLS_LE_LOX10, arsp->rel_roffset, sdp->sd_name));
803		arsp->rel_rtype = R_SPARC_TLS_LE_LOX10;
804		return (FIX_RELOC);
805
806	case R_SPARC_TLS_IE_LO10:
807	case R_SPARC_TLS_GD_LO10:
808		/*
809		 * Current instruction is:
810		 *
811		 *	or r1, %lo(x), r2
812		 *		or
813		 *	add r1, %lo(x), r2
814		 *
815		 *
816		 * Need to udpate this to:
817		 *
818		 *	xor r1, %lox(x), r2
819		 */
820		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
821		    R_SPARC_TLS_LE_LOX10, arsp->rel_roffset, sdp->sd_name));
822		*offset = TLS_GD_LE_XOR |
823		    (*offset & (FM3_REG_MSK_RS1 | FM3_REG_MSK_RD));
824		arsp->rel_rtype = R_SPARC_TLS_LE_LOX10;
825		return (FIX_RELOC);
826
827	case R_SPARC_TLS_IE_LD:
828	case R_SPARC_TLS_IE_LDX:
829		/*
830		 * Current instruction:
831		 * 	ld{x}	[r1 + r2], r3
832		 *
833		 * Need to update this to:
834		 *
835		 *	mov	r2, r3   (or  %g0, r2, r3)
836		 */
837		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
838		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
839		*offset = ((*offset) & (FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) |
840		    TLS_IE_LE_OR;
841		return (FIX_DONE);
842
843	case R_SPARC_TLS_LDO_ADD:
844	case R_SPARC_TLS_GD_ADD:
845		/*
846		 * Current instruction is:
847		 *
848		 *	add gptr_reg, r2, r3
849		 *
850		 * Need to updated this to:
851		 *
852		 *	add %g7, r2, r3
853		 */
854		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
855		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
856		*offset = *offset & (~FM3_REG_MSK_RS1);
857		*offset = *offset | (REG_G7 << 14);
858		return (FIX_DONE);
859
860	case R_SPARC_TLS_LDM_CALL:
861		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
862		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
863		*offset = TLS_LD_LE_CLRO0;
864		return (FIX_DONE);
865
866	case R_SPARC_TLS_LDM_HI22:
867	case R_SPARC_TLS_LDM_LO10:
868	case R_SPARC_TLS_LDM_ADD:
869	case R_SPARC_TLS_IE_ADD:
870	case R_SPARC_TLS_GD_CALL:
871		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
872		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
873		*offset = M_NOP;
874		return (FIX_DONE);
875	}
876	return (FIX_RELOC);
877}
878
879#define	GOTOP_ADDINST	0x80000000	/* add %g0, %g0, %g0 */
880
881static Fixupret
882gotop_fixups(Ofl_desc *ofl, Rel_desc *arsp)
883{
884	Sym_desc	*sdp = arsp->rel_sym;
885	Word		rtype = arsp->rel_rtype;
886	uint_t		*offset;
887	const char	*ifl_name;
888
889	switch (rtype) {
890	case R_SPARC_GOTDATA_OP_HIX22:
891		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
892		    R_SPARC_GOTDATA_HIX22, arsp->rel_roffset, sdp->sd_name));
893		arsp->rel_rtype = R_SPARC_GOTDATA_HIX22;
894		return (FIX_RELOC);
895
896	case R_SPARC_GOTDATA_OP_LOX10:
897		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
898		    R_SPARC_GOTDATA_LOX10, arsp->rel_roffset, sdp->sd_name));
899		arsp->rel_rtype = R_SPARC_GOTDATA_LOX10;
900		return (FIX_RELOC);
901
902	case R_SPARC_GOTDATA_OP:
903		/*
904		 * Current instruction:
905		 * 	ld{x}	[r1 + r2], r3
906		 *
907		 * Need to update this to:
908		 *
909		 *	add	r1, r2, r3
910		 */
911		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH, rtype,
912		    R_SPARC_NONE, arsp->rel_roffset, sdp->sd_name));
913		offset = (uint_t *)(uintptr_t)(arsp->rel_roffset +
914		    _elf_getxoff(arsp->rel_isdesc->is_indata) +
915		    (uintptr_t)arsp->rel_osdesc->os_outdata->d_buf);
916
917		*offset = ((*offset) & (FM3_REG_MSK_RS1 |
918		    FM3_REG_MSK_RS2 | FM3_REG_MSK_RD)) | GOTOP_ADDINST;
919		return (FIX_DONE);
920	}
921	/*
922	 * We should not get here
923	 */
924	if (arsp->rel_isdesc->is_file)
925		ifl_name = arsp->rel_isdesc->is_file->ifl_name;
926	else
927		ifl_name = MSG_INTL(MSG_STR_NULL);
928
929	eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTFIX),
930	    conv_reloc_SPARC_type(arsp->rel_rtype, 0),
931	    ifl_name, demangle(arsp->rel_sname));
932
933	assert(0);
934	return (FIX_ERROR);
935}
936
937uintptr_t
938ld_do_activerelocs(Ofl_desc *ofl)
939{
940	Rel_desc	*arsp;
941	Rel_cache	*rcp;
942	Listnode	*lnp;
943	uintptr_t	return_code = 1;
944	Word		flags = ofl->ofl_flags;
945	Word		dtflags1 = ofl->ofl_dtflags_1;
946
947	DBG_CALL(Dbg_reloc_doact_title(ofl->ofl_lml));
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	 * If we are adding a output relocation against a section
1382	 * symbol (non-RELATIVE) then mark that section.  These sections
1383	 * will be added to the .dynsym symbol table.
1384	 */
1385	if (sdp && (rsp->rel_rtype != M_R_RELATIVE) &&
1386	    ((flags & FLG_REL_SCNNDX) ||
1387	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))) {
1388
1389		/*
1390		 * If this is a COMMON symbol - no output section
1391		 * exists yet - (it's created as part of sym_validate()).
1392		 * So - we mark here that when it's created it should
1393		 * be tagged with the FLG_OS_OUTREL flag.
1394		 */
1395		if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1396		    (sdp->sd_sym->st_shndx == SHN_COMMON)) {
1397			if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS)
1398				ofl->ofl_flags1 |= FLG_OF1_BSSOREL;
1399			else
1400				ofl->ofl_flags1 |= FLG_OF1_TLSOREL;
1401		} else {
1402			Os_desc	*osp = sdp->sd_isc->is_osdesc;
1403
1404			if ((osp->os_flags & FLG_OS_OUTREL) == 0) {
1405				ofl->ofl_dynshdrcnt++;
1406				osp->os_flags |= FLG_OS_OUTREL;
1407			}
1408		}
1409	}
1410
1411	*orsp = *rsp;
1412	orsp->rel_flags |= flags;
1413
1414	rcp->rc_free++;
1415	ofl->ofl_outrelscnt++;
1416
1417	if (flags & FLG_REL_GOT)
1418		ofl->ofl_relocgotsz += (Xword)sizeof (Rela);
1419	else if (flags & FLG_REL_PLT)
1420		ofl->ofl_relocpltsz += (Xword)sizeof (Rela);
1421	else if (flags & FLG_REL_BSS)
1422		ofl->ofl_relocbsssz += (Xword)sizeof (Rela);
1423	else if (flags & FLG_REL_NOINFO)
1424		ofl->ofl_relocrelsz += (Xword)sizeof (Rela);
1425	else
1426		orsp->rel_osdesc->os_szoutrels += (Xword)sizeof (Rela);
1427
1428	if (orsp->rel_rtype == M_R_RELATIVE)
1429		ofl->ofl_relocrelcnt++;
1430
1431#if	defined(_ELF64)
1432	/*
1433	 * When building a 64-bit object any R_SPARC_WDISP30 relocation is given
1434	 * a plt padding entry, unless we're building a relocatable object
1435	 * (ld -r) or -b is in effect.
1436	 */
1437	if ((orsp->rel_rtype == R_SPARC_WDISP30) &&
1438	    ((ofl->ofl_flags & (FLG_OF_BFLAG | FLG_OF_RELOBJ)) == 0) &&
1439	    ((orsp->rel_sym->sd_flags & FLG_SY_PLTPAD) == 0)) {
1440		ofl->ofl_pltpad++;
1441		orsp->rel_sym->sd_flags |= FLG_SY_PLTPAD;
1442	}
1443#endif
1444	/*
1445	 * We don't perform sorting on PLT relocations because
1446	 * they have already been assigned a PLT index and if we
1447	 * were to sort them we would have to re-assign the plt indexes.
1448	 */
1449	if (!(flags & FLG_REL_PLT))
1450		ofl->ofl_reloccnt++;
1451
1452	/*
1453	 * Insure a GLOBAL_OFFSET_TABLE is generated if required.
1454	 */
1455	if (IS_GOT_REQUIRED(orsp->rel_rtype))
1456		ofl->ofl_flags |= FLG_OF_BLDGOT;
1457
1458	/*
1459	 * Identify and possibly warn of a displacement relocation.
1460	 */
1461	if (orsp->rel_flags & FLG_REL_DISP) {
1462		ofl->ofl_dtflags_1 |= DF_1_DISPRELPND;
1463
1464		if (ofl->ofl_flags & FLG_OF_VERBOSE)
1465			ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL4), orsp, ofl);
1466	}
1467	DBG_CALL(Dbg_reloc_ors_entry(ofl->ofl_lml, ELF_DBG_LD, SHT_RELA,
1468	    M_MACH, orsp));
1469	return (1);
1470}
1471
1472/*
1473 * Process relocation against a register symbol.  Note, of -z muldefs is in
1474 * effect there may have been multiple register definitions, which would have
1475 * been processed as non-fatal, with the first definition winning.  But, we
1476 * will also process multiple relocations for these multiple definitions.  In
1477 * this case we must only preserve the relocation for the definition that was
1478 * kept.  The sad part is that register relocations don't typically specify
1479 * the register symbol with which they are associated, so we might have to
1480 * search the input files global symbols to determine if this relocation is
1481 * appropriate.
1482 */
1483uintptr_t
1484ld_reloc_register(Rel_desc * rsp, Is_desc * isp, Ofl_desc * ofl)
1485{
1486	if (ofl->ofl_flags & FLG_OF_MULDEFS) {
1487		Ifl_desc *	ifl = isp->is_file;
1488		Sym_desc *	sdp = rsp->rel_sym;
1489
1490		if (sdp == 0) {
1491			Xword		offset = rsp->rel_roffset;
1492			Word		ndx;
1493
1494			for (ndx = ifl->ifl_locscnt;
1495			    ndx < ifl->ifl_symscnt; ndx++) {
1496				if (((sdp = ifl->ifl_oldndx[ndx]) != 0) &&
1497				    (sdp->sd_flags & FLG_SY_REGSYM) &&
1498				    (sdp->sd_sym->st_value == offset))
1499					break;
1500			}
1501		}
1502		if (sdp && (sdp->sd_file != ifl))
1503			return (1);
1504	}
1505	return (ld_add_outrel((rsp->rel_flags | FLG_REL_REG), rsp, ofl));
1506}
1507
1508/*
1509 * process relocation for a LOCAL symbol
1510 */
1511uintptr_t
1512ld_reloc_local(Rel_desc * rsp, Ofl_desc * ofl)
1513{
1514	Word		flags = ofl->ofl_flags;
1515	Sym_desc	*sdp = rsp->rel_sym;
1516	Word		shndx = sdp->sd_sym->st_shndx;
1517
1518	/*
1519	 * if ((shared object) and (not pc relative relocation) and
1520	 *    (not against ABS symbol))
1521	 * then
1522	 *	if (rtype != R_SPARC_32)
1523	 *	then
1524	 *		build relocation against section
1525	 *	else
1526	 *		build R_SPARC_RELATIVE
1527	 *	fi
1528	 * fi
1529	 */
1530	if ((flags & FLG_OF_SHAROBJ) && (rsp->rel_flags & FLG_REL_LOAD) &&
1531	    !(IS_PC_RELATIVE(rsp->rel_rtype)) &&
1532	    !(IS_GOT_BASED(rsp->rel_rtype)) &&
1533	    !(rsp->rel_isdesc != NULL &&
1534	    (rsp->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof)) &&
1535	    (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
1536	    (shndx != SHN_ABS) || (sdp->sd_aux && sdp->sd_aux->sa_symspec))) {
1537		Word	ortype = rsp->rel_rtype;
1538
1539		if ((rsp->rel_rtype != R_SPARC_32) &&
1540		    (rsp->rel_rtype != R_SPARC_PLT32) &&
1541		    (rsp->rel_rtype != R_SPARC_64))
1542			return (ld_add_outrel((FLG_REL_SCNNDX | FLG_REL_ADVAL),
1543			    rsp, ofl));
1544
1545		rsp->rel_rtype = R_SPARC_RELATIVE;
1546		if (ld_add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR)
1547			return (S_ERROR);
1548		rsp->rel_rtype = ortype;
1549		return (1);
1550	}
1551
1552	/*
1553	 * If the relocation is against a 'non-allocatable' section
1554	 * and we can not resolve it now - then give a warning
1555	 * message.
1556	 *
1557	 * We can not resolve the symbol if either:
1558	 *	a) it's undefined
1559	 *	b) it's defined in a shared library and a
1560	 *	   COPY relocation hasn't moved it to the executable
1561	 *
1562	 * Note: because we process all of the relocations against the
1563	 *	text segment before any others - we know whether
1564	 *	or not a copy relocation will be generated before
1565	 *	we get here (see reloc_init()->reloc_segments()).
1566	 */
1567	if (!(rsp->rel_flags & FLG_REL_LOAD) &&
1568	    ((shndx == SHN_UNDEF) ||
1569	    ((sdp->sd_ref == REF_DYN_NEED) &&
1570	    ((sdp->sd_flags & FLG_SY_MVTOCOMM) == 0)))) {
1571		/*
1572		 * If the relocation is against a SHT_SUNW_ANNOTATE
1573		 * section - then silently ignore that the relocation
1574		 * can not be resolved.
1575		 */
1576		if (rsp->rel_osdesc &&
1577		    (rsp->rel_osdesc->os_shdr->sh_type == SHT_SUNW_ANNOTATE))
1578			return (0);
1579		(void) eprintf(ofl->ofl_lml, ERR_WARNING,
1580		    MSG_INTL(MSG_REL_EXTERNSYM),
1581		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1582		    rsp->rel_isdesc->is_file->ifl_name,
1583		    demangle(rsp->rel_sname), rsp->rel_osdesc->os_name);
1584		return (1);
1585	}
1586
1587	/*
1588	 * Perform relocation.
1589	 */
1590	return (ld_add_actrel(NULL, rsp, ofl));
1591}
1592
1593uintptr_t
1594ld_reloc_GOTOP(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
1595{
1596	Word	rtype = rsp->rel_rtype;
1597
1598	if (!local) {
1599		/*
1600		 * When binding to a external symbol, no fixups are required
1601		 * and the GOTDATA_OP relocation can be ignored.
1602		 */
1603		if (rtype == R_SPARC_GOTDATA_OP)
1604			return (1);
1605		return (ld_reloc_GOT_relative(local, rsp, ofl));
1606	}
1607
1608	/*
1609	 * When binding to a local symbol the relocations can be transitioned:
1610	 *
1611	 *	R_*_GOTDATA_OP_HIX22 -> R_*_GOTDATA_HIX22
1612	 *	R_*_GOTDATA_OP_LOX10 -> R_*_GOTDATA_LOX10
1613	 *	R_*_GOTDATA_OP ->	instruction fixup
1614	 */
1615	return (ld_add_actrel(FLG_REL_GOTFIX, rsp, ofl));
1616}
1617
1618uintptr_t
1619ld_reloc_TLS(Boolean local, Rel_desc * rsp, Ofl_desc * ofl)
1620{
1621	Word		rtype = rsp->rel_rtype;
1622	Sym_desc	*sdp = rsp->rel_sym;
1623	Word		flags = ofl->ofl_flags;
1624	Word		rflags;
1625	Gotndx		*gnp;
1626
1627	/*
1628	 * all TLS relocations are illegal in a static executable.
1629	 */
1630	if ((ofl->ofl_flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
1631	    (FLG_OF_STATIC | FLG_OF_EXEC)) {
1632		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
1633		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1634		    rsp->rel_isdesc->is_file->ifl_name,
1635		    demangle(rsp->rel_sname));
1636		return (S_ERROR);
1637	}
1638
1639	/*
1640	 * Any TLS relocation must be against a STT_TLS symbol, all others
1641	 * are illegal.
1642	 */
1643	if (ELF_ST_TYPE(sdp->sd_sym->st_info) != STT_TLS) {
1644		Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
1645
1646		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
1647		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1648		    ifl->ifl_name, demangle(rsp->rel_sname),
1649		    conv_sym_info_type(ifl->ifl_ehdr->e_machine,
1650		    ELF_ST_TYPE(sdp->sd_sym->st_info), 0));
1651		return (S_ERROR);
1652	}
1653
1654	/*
1655	 * We're a executable - use either the IE or LE
1656	 * access model.
1657	 */
1658	if (flags & FLG_OF_EXEC) {
1659		/*
1660		 * If we are using either IE or LE reference
1661		 * model set the DF_STATIC_TLS flag.
1662		 */
1663		ofl->ofl_dtflags |= DF_STATIC_TLS;
1664
1665		if (!local) {
1666			/*
1667			 * IE access model
1668			 */
1669			/*
1670			 * When building a executable - these relocations
1671			 * can be ignored.
1672			 */
1673			if ((rtype == R_SPARC_TLS_IE_LD) ||
1674			    (rtype == R_SPARC_TLS_IE_LDX) ||
1675			    (rtype == R_SPARC_TLS_IE_ADD))
1676				return (1);
1677
1678			/*
1679			 * It's not possible for LD or LE reference
1680			 * models to reference a symbol external to
1681			 * the current object.
1682			 */
1683			if (IS_TLS_LD(rtype) || IS_TLS_LE(rtype)) {
1684				eprintf(ofl->ofl_lml, ERR_FATAL,
1685				    MSG_INTL(MSG_REL_TLSBND),
1686				    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1687				    rsp->rel_isdesc->is_file->ifl_name,
1688				    demangle(rsp->rel_sname),
1689				    sdp->sd_file->ifl_name);
1690				return (S_ERROR);
1691			}
1692
1693			/*
1694			 * Assign a GOT entry for static TLS references
1695			 */
1696			if (((rtype == R_SPARC_TLS_GD_HI22) ||
1697			    (rtype == R_SPARC_TLS_GD_LO10) ||
1698			    (rtype == R_SPARC_TLS_IE_HI22) ||
1699			    (rtype == R_SPARC_TLS_IE_LO10)) &&
1700			    ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
1701			    GOT_REF_TLSIE, ofl, rsp)) == 0)) {
1702				if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp,
1703				    GOT_REF_TLSIE, ofl, rsp, sdp) == S_ERROR)
1704					return (S_ERROR);
1705				rsp->rel_rtype = M_R_TPOFF;
1706				if (ld_add_outrel((FLG_REL_GOT | FLG_REL_STLS),
1707				    rsp, ofl) == S_ERROR)
1708					return (S_ERROR);
1709				rsp->rel_rtype = rtype;
1710			}
1711
1712			if (IS_TLS_IE(rtype))
1713				return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
1714
1715			/*
1716			 * If (GD) reference models - fixups
1717			 * are required.
1718			 */
1719			return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
1720			    rsp, ofl));
1721		}
1722		/*
1723		 * LE access model
1724		 */
1725		if (IS_TLS_LE(rtype))
1726			return (ld_add_actrel(FLG_REL_STLS, rsp, ofl));
1727
1728		/*
1729		 * When building a executable - these relocations
1730		 * can be ignored.
1731		 */
1732		if (rtype == R_SPARC_TLS_IE_ADD)
1733			return (1);
1734
1735		return (ld_add_actrel((FLG_REL_TLSFIX | FLG_REL_STLS),
1736		    rsp, ofl));
1737	}
1738
1739	/*
1740	 * Building a shared object
1741	 */
1742
1743	/*
1744	 * Building a shared object - only GD & LD access models
1745	 * will work here.
1746	 */
1747	if (IS_TLS_IE(rtype) || IS_TLS_LE(rtype)) {
1748		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSIE),
1749		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1750		    rsp->rel_isdesc->is_file->ifl_name,
1751		    demangle(rsp->rel_sname));
1752		return (S_ERROR);
1753	}
1754
1755	/*
1756	 * LD access mode can only bind to local symbols.
1757	 */
1758	if (!local && IS_TLS_LD(rtype)) {
1759		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
1760		    conv_reloc_SPARC_type(rsp->rel_rtype, 0),
1761		    rsp->rel_isdesc->is_file->ifl_name,
1762		    demangle(rsp->rel_sname),
1763		    sdp->sd_file->ifl_name);
1764		return (S_ERROR);
1765	}
1766
1767	/*
1768	 * For dynamic TLS references - ADD relocations
1769	 * are ignored.
1770	 */
1771	if ((rtype == R_SPARC_TLS_GD_ADD) || (rtype == R_SPARC_TLS_LDM_ADD) ||
1772	    (rtype == R_SPARC_TLS_LDO_ADD))
1773		return (1);
1774
1775	/*
1776	 * Assign a GOT entry for a dynamic TLS reference.
1777	 */
1778	if (((rtype == R_SPARC_TLS_LDM_HI22) ||
1779	    (rtype == R_SPARC_TLS_LDM_LO10)) &&
1780	    ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
1781	    GOT_REF_TLSLD, ofl, rsp)) == 0)) {
1782		if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSLD,
1783		    ofl, rsp, sdp) == S_ERROR)
1784			return (S_ERROR);
1785		rsp->rel_rtype = M_R_DTPMOD;
1786		rflags = FLG_REL_GOT | FLG_REL_MTLS;
1787		if (local)
1788			rflags |= FLG_REL_SCNNDX;
1789
1790		if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
1791			return (S_ERROR);
1792
1793		rsp->rel_rtype = rtype;
1794
1795	} else if (((rtype == R_SPARC_TLS_GD_HI22) || (rtype ==
1796	    R_SPARC_TLS_GD_LO10)) && ((gnp = ld_find_gotndx(&(sdp->sd_GOTndxs),
1797	    GOT_REF_TLSGD, ofl, rsp)) == 0)) {
1798		if (ld_assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_TLSGD,
1799		    ofl, rsp, sdp) == S_ERROR)
1800			return (S_ERROR);
1801		rsp->rel_rtype = M_R_DTPMOD;
1802		rflags = FLG_REL_GOT | FLG_REL_DTLS;
1803		if (local)
1804			rflags |= FLG_REL_SCNNDX;
1805
1806		if (ld_add_outrel(rflags, rsp, ofl) == S_ERROR)
1807			return (S_ERROR);
1808
1809		if (local == TRUE) {
1810			rsp->rel_rtype = M_R_DTPOFF;
1811			if (ld_add_actrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
1812			    ofl) == S_ERROR)
1813				return (S_ERROR);
1814		} else {
1815			rsp->rel_rtype = M_R_DTPOFF;
1816			if (ld_add_outrel((FLG_REL_GOT | FLG_REL_DTLS), rsp,
1817			    ofl) == S_ERROR)
1818				return (S_ERROR);
1819		}
1820		rsp->rel_rtype = rtype;
1821	}
1822	/*
1823	 * For GD/LD TLS reference - TLS_{GD,LD}_CALL, this will eventually
1824	 * cause a call to __tls_get_addr().  Let's convert this
1825	 * relocation to that symbol now, and prepare for the PLT magic.
1826	 */
1827	if ((rtype == R_SPARC_TLS_GD_CALL) || (rtype == R_SPARC_TLS_LDM_CALL)) {
1828		Sym_desc *	tlsgetsym;
1829
1830		if ((tlsgetsym = ld_sym_add_u(MSG_ORIG(MSG_SYM_TLSGETADDR_U),
1831		    ofl)) == (Sym_desc *)S_ERROR)
1832			return (S_ERROR);
1833		rsp->rel_sym = tlsgetsym;
1834		rsp->rel_sname = tlsgetsym->sd_name;
1835		rsp->rel_rtype = R_SPARC_WPLT30;
1836		if (ld_reloc_plt(rsp, ofl) == S_ERROR)
1837			return (S_ERROR);
1838		rsp->rel_sym = sdp;
1839		rsp->rel_sname = sdp->sd_name;
1840		rsp->rel_rtype = rtype;
1841		return (1);
1842	}
1843
1844	if (IS_TLS_LD(rtype))
1845		return (ld_add_actrel(FLG_REL_MTLS, rsp, ofl));
1846
1847	return (ld_add_actrel(FLG_REL_DTLS, rsp, ofl));
1848}
1849
1850/*
1851 * ld_allocate_got: if a GOT is to be made, after the section is built this
1852 * function is called to allocate all the GOT slots.  The allocation is
1853 * deferred until after all GOTs have been counted and sorted according
1854 * to their size, for only then will we know how to allocate them on
1855 * a processor like SPARC which has different models for addressing the
1856 * GOT.  SPARC has two: small and large, small uses a signed 13-bit offset
1857 * into the GOT, whereas large uses an unsigned 32-bit offset.
1858 */
1859static	Sword small_index;	/* starting index for small GOT entries */
1860static	Sword large_index;	/* starting index for large GOT entries */
1861
1862uintptr_t
1863ld_assign_got(Ofl_desc *ofl, Sym_desc * sdp)
1864{
1865	Listnode *	lnp;
1866	Gotndx *	gnp;
1867
1868	for (LIST_TRAVERSE(&sdp->sd_GOTndxs, lnp, gnp)) {
1869		uint_t	gotents;
1870		Gotref	gref;
1871		gref = gnp->gn_gotref;
1872		if ((gref == GOT_REF_TLSGD) || (gref == GOT_REF_TLSLD))
1873			gotents = 2;
1874		else
1875			gotents = 1;
1876
1877		switch (gnp->gn_gotndx) {
1878		case M_GOT_SMALL:
1879			gnp->gn_gotndx = small_index;
1880			small_index += gotents;
1881			if (small_index == 0)
1882				small_index = M_GOT_XNumber;
1883			break;
1884		case M_GOT_LARGE:
1885			gnp->gn_gotndx = large_index;
1886			large_index += gotents;
1887			break;
1888		default:
1889			eprintf(ofl->ofl_lml, ERR_FATAL,
1890			    MSG_INTL(MSG_REL_ASSIGNGOT),
1891			    EC_XWORD(gnp->gn_gotndx), demangle(sdp->sd_name));
1892			return (S_ERROR);
1893		}
1894	}
1895	return (1);
1896}
1897
1898/*
1899 * Search the GOT index list for a GOT entry with the proper addend.
1900 */
1901Gotndx *
1902ld_find_gotndx(List * lst, Gotref gref, Ofl_desc * ofl, Rel_desc * rdesc)
1903{
1904	Listnode *	lnp;
1905	Gotndx *	gnp;
1906
1907	if ((gref == GOT_REF_TLSLD) && ofl->ofl_tlsldgotndx)
1908		return (ofl->ofl_tlsldgotndx);
1909
1910	for (LIST_TRAVERSE(lst, lnp, gnp)) {
1911		if ((rdesc->rel_raddend == gnp->gn_addend) &&
1912		    (gref == gnp->gn_gotref))
1913			return (gnp);
1914	}
1915	return ((Gotndx *)0);
1916}
1917
1918Xword
1919ld_calc_got_offset(Rel_desc * rdesc, Ofl_desc * ofl)
1920{
1921	Os_desc		*osp = ofl->ofl_osgot;
1922	Sym_desc	*sdp = rdesc->rel_sym;
1923	Xword		gotndx;
1924	Gotref		gref;
1925	Gotndx		*gnp;
1926
1927	if (rdesc->rel_flags & FLG_REL_DTLS)
1928		gref = GOT_REF_TLSGD;
1929	else if (rdesc->rel_flags & FLG_REL_MTLS)
1930		gref = GOT_REF_TLSLD;
1931	else if (rdesc->rel_flags & FLG_REL_STLS)
1932		gref = GOT_REF_TLSIE;
1933	else
1934		gref = GOT_REF_GENERIC;
1935
1936	gnp = ld_find_gotndx(&(sdp->sd_GOTndxs), gref, ofl, rdesc);
1937	assert(gnp);
1938
1939	gotndx = (Xword)gnp->gn_gotndx;
1940
1941	if ((rdesc->rel_flags & FLG_REL_DTLS) &&
1942	    (rdesc->rel_rtype == M_R_DTPOFF))
1943		gotndx++;
1944
1945	return ((Xword)((osp->os_shdr->sh_addr) + (gotndx * M_GOT_ENTSIZE) +
1946	    (-neggotoffset * M_GOT_ENTSIZE)));
1947}
1948
1949uintptr_t
1950ld_assign_gotndx(List * lst, Gotndx * pgnp, Gotref gref, Ofl_desc * ofl,
1951    Rel_desc * rsp, Sym_desc * sdp)
1952{
1953	Xword		raddend;
1954	Gotndx *	gnp, * _gnp;
1955	Listnode *	lnp, * plnp;
1956	uint_t		gotents;
1957
1958	raddend = rsp->rel_raddend;
1959	if (pgnp && (pgnp->gn_addend == raddend) && (pgnp->gn_gotref == gref)) {
1960		/*
1961		 * If an entry for this addend already exists, determine if it
1962		 * should be changed to a SMALL got.
1963		 */
1964		if ((pgnp->gn_gotndx != M_GOT_SMALL) &&
1965		    (rsp->rel_rtype == R_SPARC_GOT13)) {
1966			smlgotcnt++;
1967			pgnp->gn_gotndx = M_GOT_SMALL;
1968			sdp->sd_flags |= FLG_SY_SMGOT;
1969		}
1970		return (1);
1971	}
1972
1973	if ((gref == GOT_REF_TLSGD) || (gref == GOT_REF_TLSLD))
1974		gotents = 2;
1975	else
1976		gotents = 1;
1977
1978	plnp = 0;
1979	for (LIST_TRAVERSE(lst, lnp, _gnp)) {
1980		if (_gnp->gn_addend > raddend)
1981			break;
1982		plnp = lnp;
1983	}
1984
1985	/*
1986	 * Allocate a new entry.
1987	 */
1988	if ((gnp = libld_calloc(sizeof (Gotndx), 1)) == 0)
1989		return (S_ERROR);
1990	gnp->gn_addend = raddend;
1991	gnp->gn_gotref = gref;
1992	ofl->ofl_gotcnt += gotents;
1993
1994	if (rsp->rel_rtype == R_SPARC_GOT13) {
1995		gnp->gn_gotndx = M_GOT_SMALL;
1996		smlgotcnt++;
1997		sdp->sd_flags |= FLG_SY_SMGOT;
1998	} else
1999		gnp->gn_gotndx = M_GOT_LARGE;
2000
2001	if (gref == GOT_REF_TLSLD) {
2002		ofl->ofl_tlsldgotndx = gnp;
2003		return (1);
2004	}
2005
2006	if (plnp == 0) {
2007		/*
2008		 * Insert at head of list
2009		 */
2010		if (list_prependc(lst, (void *)gnp) == 0)
2011			return (S_ERROR);
2012	} else if (_gnp->gn_addend > raddend) {
2013		/*
2014		 * Insert in middle of lest
2015		 */
2016		if (list_insertc(lst, (void *)gnp, plnp) == 0)
2017			return (S_ERROR);
2018	} else {
2019		/*
2020		 * Append to tail of list
2021		 */
2022		if (list_appendc(lst, (void *)gnp) == 0)
2023			return (S_ERROR);
2024	}
2025	return (1);
2026}
2027
2028void
2029ld_assign_plt_ndx(Sym_desc * sdp, Ofl_desc *ofl)
2030{
2031	sdp->sd_aux->sa_PLTndx = 1 + ofl->ofl_pltcnt++;
2032}
2033
2034
2035uintptr_t
2036ld_allocate_got(Ofl_desc * ofl)
2037{
2038	Sym_desc *	sdp;
2039	Addr		addr;
2040
2041	/*
2042	 * Sanity check -- is this going to fit at all?
2043	 */
2044	if (smlgotcnt >= M_GOT_MAXSMALL) {
2045		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_SMALLGOT),
2046		    EC_WORD(smlgotcnt), M_GOT_MAXSMALL);
2047		return (S_ERROR);
2048	}
2049
2050	/*
2051	 * Set starting offset to be either 0, or a negative index into
2052	 * the GOT based on the number of small symbols we've got.
2053	 */
2054	neggotoffset = ((smlgotcnt > (M_GOT_MAXSMALL / 2)) ?
2055	    -((smlgotcnt - (M_GOT_MAXSMALL / 2))) : 0);
2056
2057	/*
2058	 * Initialize the large and small got offsets (used in assign_got()).
2059	 */
2060	small_index = neggotoffset == 0 ? M_GOT_XNumber : neggotoffset;
2061	large_index = neggotoffset + smlgotcnt;
2062
2063	/*
2064	 * Assign bias to GOT symbols.
2065	 */
2066	addr = -neggotoffset * M_GOT_ENTSIZE;
2067	if (sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL), SYM_NOHASH, 0, ofl))
2068		sdp->sd_sym->st_value = addr;
2069	if (sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl))
2070		sdp->sd_sym->st_value = addr;
2071
2072	if (ofl->ofl_tlsldgotndx) {
2073		ofl->ofl_tlsldgotndx->gn_gotndx = large_index;
2074		large_index += 2;
2075	}
2076	return (1);
2077}
2078
2079
2080/*
2081 * Initializes .got[0] with the _DYNAMIC symbol value.
2082 */
2083uintptr_t
2084ld_fillin_gotplt(Ofl_desc * ofl)
2085{
2086	if (ofl->ofl_osgot) {
2087		Sym_desc *	sdp;
2088
2089		if ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_DYNAMIC_U),
2090		    SYM_NOHASH, 0, ofl)) != NULL) {
2091			uchar_t	*genptr = ((uchar_t *)
2092			    ofl->ofl_osgot->os_outdata->d_buf +
2093			    (-neggotoffset * M_GOT_ENTSIZE) +
2094			    (M_GOT_XDYNAMIC * M_GOT_ENTSIZE));
2095			/* LINTED */
2096			*((Xword *)genptr) = sdp->sd_sym->st_value;
2097		}
2098	}
2099	return (1);
2100}
2101