xref: /titanic_41/usr/src/cmd/sgs/libld/common/relocate.c (revision e059026e2da8f12ef0ebea9d686d67f32660cfc0)
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 2009 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 
30 /*
31  * set-up for relocations
32  */
33 
34 #define	ELF_TARGET_AMD64
35 #define	ELF_TARGET_SPARC
36 
37 #include	<string.h>
38 #include	<stdio.h>
39 #include	<alloca.h>
40 #include	<debug.h>
41 #include	"msg.h"
42 #include	"_libld.h"
43 
44 /*
45  * Set up the relocation table flag test macros so that they use the
46  * relocation table for the current target machine.
47  */
48 #define	IS_PLT(X)	RELTAB_IS_PLT(X, ld_targ.t_mr.mr_reloc_table)
49 #define	IS_GOT_RELATIVE(X) \
50 	RELTAB_IS_GOT_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
51 #define	IS_GOT_PC(X)	RELTAB_IS_GOT_PC(X, ld_targ.t_mr.mr_reloc_table)
52 #define	IS_GOTPCREL(X)	RELTAB_IS_GOTPCREL(X, ld_targ.t_mr.mr_reloc_table)
53 #define	IS_GOT_BASED(X)	RELTAB_IS_GOT_BASED(X, ld_targ.t_mr.mr_reloc_table)
54 #define	IS_GOT_OPINS(X)	RELTAB_IS_GOT_OPINS(X, ld_targ.t_mr.mr_reloc_table)
55 #define	IS_GOT_REQUIRED(X) \
56 	RELTAB_IS_GOT_REQUIRED(X, ld_targ.t_mr.mr_reloc_table)
57 #define	IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
58 #define	IS_ADD_RELATIVE(X) \
59 	RELTAB_IS_ADD_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
60 #define	IS_REGISTER(X)	RELTAB_IS_REGISTER(X, ld_targ.t_mr.mr_reloc_table)
61 #define	IS_NOTSUP(X)	RELTAB_IS_NOTSUP(X, ld_targ.t_mr.mr_reloc_table)
62 #define	IS_SEG_RELATIVE(X) \
63 	RELTAB_IS_SEG_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
64 #define	IS_EXTOFFSET(X)	RELTAB_IS_EXTOFFSET(X, ld_targ.t_mr.mr_reloc_table)
65 #define	IS_SEC_RELATIVE(X) \
66 	RELTAB_IS_SEC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
67 #define	IS_TLS_INS(X)	RELTAB_IS_TLS_INS(X, ld_targ.t_mr.mr_reloc_table)
68 #define	IS_TLS_GD(X)	RELTAB_IS_TLS_GD(X, ld_targ.t_mr.mr_reloc_table)
69 #define	IS_TLS_LD(X)	RELTAB_IS_TLS_LD(X, ld_targ.t_mr.mr_reloc_table)
70 #define	IS_TLS_IE(X)	RELTAB_IS_TLS_IE(X, ld_targ.t_mr.mr_reloc_table)
71 #define	IS_TLS_LE(X)	RELTAB_IS_TLS_LE(X, ld_targ.t_mr.mr_reloc_table)
72 #define	IS_LOCALBND(X)	RELTAB_IS_LOCALBND(X, ld_targ.t_mr.mr_reloc_table)
73 #define	IS_SIZE(X)	RELTAB_IS_SIZE(X, ld_targ.t_mr.mr_reloc_table)
74 
75 /*
76  * Structure to hold copy relocation items.
77  */
78 typedef struct copy_rel {
79 	Sym_desc	*c_sdp;		/* symbol descriptor to be copied */
80 	Addr 		c_val;		/* original symbol value */
81 } Copy_rel;
82 
83 /*
84  * For each copy relocation symbol, determine if the symbol is:
85  * 	1) to be *disp* relocated at runtime
86  *	2) a reference symbol for *disp* relocation
87  *	3) possibly *disp* relocated at ld time.
88  *
89  * The first and the second are serious errors.
90  */
91 static void
92 is_disp_copied(Ofl_desc *ofl, Copy_rel *crp)
93 {
94 	Ifl_desc	*ifl = crp->c_sdp->sd_file;
95 	Sym_desc	*sdp = crp->c_sdp;
96 	Addr		symaddr = crp->c_val;
97 	Is_desc		*irel;
98 	Aliste		idx;
99 	Conv_inv_buf_t	inv_buf;
100 
101 	/*
102 	 * This symbol may not be *disp* relocated at run time, but could
103 	 * already have been *disp* relocated when the shared object was
104 	 * created.  Warn the user.
105 	 */
106 	if ((ifl->ifl_flags & FLG_IF_DISPDONE) &&
107 	    (ofl->ofl_flags & FLG_OF_VERBOSE))
108 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
109 		    conv_reloc_type(ifl->ifl_ehdr->e_machine,
110 		    ld_targ.t_m.m_r_copy, 0, &inv_buf),
111 		    ifl->ifl_name, demangle(sdp->sd_name));
112 
113 	if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0)
114 		return;
115 
116 	/*
117 	 * Traverse the input relocation sections.
118 	 */
119 	for (APLIST_TRAVERSE(ifl->ifl_relsect, idx, irel)) {
120 		Sym_desc	*rsdp;
121 		Is_desc		*trel;
122 		Rel		*rend, *reloc;
123 		Xword		rsize, entsize;
124 
125 		trel = ifl->ifl_isdesc[irel->is_shdr->sh_info];
126 		rsize = irel->is_shdr->sh_size;
127 		entsize = irel->is_shdr->sh_entsize;
128 		reloc = (Rel *)irel->is_indata->d_buf;
129 
130 		/*
131 		 * Decide entry size
132 		 */
133 		if ((entsize == 0) || (entsize > rsize)) {
134 			if (irel->is_shdr->sh_type == SHT_RELA)
135 				entsize = sizeof (Rela);
136 			else
137 				entsize = sizeof (Rel);
138 		}
139 
140 		/*
141 		 * Traverse the relocation entries.
142 		 */
143 		for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
144 		    reloc < rend;
145 		    reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
146 			const char	*str;
147 			Word		rstndx;
148 
149 			if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info,
150 			    ld_targ.t_m.m_mach)) == 0)
151 				continue;
152 
153 			/*
154 			 * First, check if this symbol is reference symbol
155 			 * for this relocation entry.
156 			 */
157 			rstndx = (Word) ELF_R_SYM(reloc->r_info);
158 			rsdp = ifl->ifl_oldndx[rstndx];
159 			if (rsdp == sdp) {
160 				if ((str = demangle(rsdp->sd_name)) !=
161 				    rsdp->sd_name) {
162 					char	*_str = alloca(strlen(str) + 1);
163 					(void) strcpy(_str, str);
164 					str = (const char *)_str;
165 				}
166 				eprintf(ofl->ofl_lml,
167 				    ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
168 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
169 				    (uint_t)ELF_R_TYPE(reloc->r_info,
170 				    ld_targ.t_m.m_mach),
171 				    0, &inv_buf), ifl->ifl_name, str,
172 				    MSG_INTL(MSG_STR_UNKNOWN),
173 				    EC_XWORD(reloc->r_offset),
174 				    demangle(sdp->sd_name));
175 			}
176 
177 			/*
178 			 * Then check if this relocation entry is relocating
179 			 * this symbol.
180 			 */
181 			if ((sdp->sd_isc != trel) ||
182 			    (reloc->r_offset < symaddr) ||
183 			    (reloc->r_offset >=
184 			    (symaddr + sdp->sd_sym->st_size)))
185 				continue;
186 
187 			/*
188 			 * This symbol is truely *disp* relocated, so should
189 			 * really be fixed by user.
190 			 */
191 			if ((str = demangle(sdp->sd_name)) != sdp->sd_name) {
192 				char	*_str = alloca(strlen(str) + 1);
193 				(void) strcpy(_str, str);
194 				str = (const char *)_str;
195 			}
196 			eprintf(ofl->ofl_lml, ERR_WARNING,
197 			    MSG_INTL(MSG_REL_DISPREL1),
198 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
199 			    (uint_t)ELF_R_TYPE(reloc->r_info,
200 			    ld_targ.t_m.m_mach), 0, &inv_buf),
201 			    ifl->ifl_name, demangle(rsdp->sd_name), str,
202 			    EC_XWORD(reloc->r_offset), str);
203 		}
204 	}
205 }
206 
207 /*
208  * The number of symbols provided by some objects can be very large.  Use a
209  * binary search to match the associated value to a symbol table entry.
210  */
211 static int
212 disp_bsearch(const void *key, const void *array)
213 {
214 	Addr		kvalue, avalue;
215 	Ssv_desc	*ssvp = (Ssv_desc *)array;
216 
217 	kvalue = *((Addr *)key);
218 	avalue = ssvp->ssv_value;
219 
220 	if (avalue > kvalue)
221 		return (-1);
222 	if ((avalue < kvalue) &&
223 	    ((avalue + ssvp->ssv_sdp->sd_sym->st_size) <= kvalue))
224 		return (1);
225 	return (0);
226 }
227 
228 /*
229  * Given a sorted list of symbols, look for a symbol in which the relocation
230  * offset falls between the [sym.st_value - sym.st_value + sym.st_size].  Since
231  * the symbol list is maintained in sorted order,  we can bail once the
232  * relocation offset becomes less than the symbol values.  The symbol is
233  * returned for use in error diagnostics.
234  */
235 static Sym_desc *
236 disp_scansyms(Ifl_desc * ifl, Rel_desc *rld, Boolean rlocal, int inspect,
237     Ofl_desc *ofl)
238 {
239 	Sym_desc	*tsdp, *rsdp;
240 	Sym		*rsym, *tsym;
241 	Ssv_desc	*ssvp;
242 	uchar_t		rtype, ttype;
243 	Addr		value;
244 
245 	/*
246 	 * Sorted symbol values have been uniquified by adding their associated
247 	 * section offset.  Uniquify the relocation offset by adding its
248 	 * associated section offset, and search for the symbol.
249 	 */
250 	value = rld->rel_roffset;
251 	if (rld->rel_isdesc->is_shdr)
252 		value += rld->rel_isdesc->is_shdr->sh_offset;
253 
254 	if ((ssvp = bsearch((void *)&value, (void *)ifl->ifl_sortsyms,
255 	    ifl->ifl_sortcnt, sizeof (Ssv_desc), &disp_bsearch)) != 0)
256 		tsdp = ssvp->ssv_sdp;
257 	else
258 		tsdp = 0;
259 
260 	if (inspect)
261 		return (tsdp);
262 
263 	/*
264 	 * Determine the relocation reference symbol and its type.
265 	 */
266 	rsdp = rld->rel_sym;
267 	rsym = rsdp->sd_sym;
268 	rtype = ELF_ST_TYPE(rsym->st_info);
269 
270 	/*
271 	 * If there is no target symbol to match the relocation offset, then the
272 	 * offset is effectively local data.  If the relocation symbol is global
273 	 * data we have a potential for this displacement relocation to be
274 	 * invalidated should the global symbol be copied.
275 	 */
276 	if (tsdp == 0) {
277 		if ((rlocal == TRUE) ||
278 		    ((rtype != STT_OBJECT) && (rtype != STT_SECTION)))
279 		return (tsdp);
280 	} else {
281 		/*
282 		 * If both symbols are local, no copy relocations can occur to
283 		 * either symbol.  Note, this test is very similar to the test
284 		 * used in ld_sym_adjust_vis().
285 		 */
286 		if ((rlocal == TRUE) &&
287 		    ((tsdp->sd_flags1 & FLG_SY1_HIDDEN) ||
288 		    (ELF_ST_BIND(tsdp->sd_sym->st_info) != STB_GLOBAL) ||
289 		    ((ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM)) &&
290 		    ((tsdp->sd_flags1 & MSK_SY1_NOAUTO) == 0))))
291 			return (tsdp);
292 
293 		/*
294 		 * Determine the relocation target symbols type.
295 		 */
296 		tsym = tsdp->sd_sym;
297 		ttype = ELF_ST_TYPE(tsym->st_info);
298 
299 		/*
300 		 * If the reference symbol is local, and the target isn't a
301 		 * data element, then no copy relocations can occur to either
302 		 * symbol.  Note, this catches pc-relative relocations against
303 		 * the _GLOBAL_OFFSET_TABLE_, which is effectively treated as
304 		 * a local symbol.
305 		 */
306 		if ((rlocal == TRUE) && (ttype != STT_OBJECT) &&
307 		    (ttype != STT_SECTION))
308 			return (tsdp);
309 
310 		/*
311 		 * Finally, one of the symbols must reference a data element.
312 		 */
313 		if ((rtype != STT_OBJECT) && (rtype != STT_SECTION) &&
314 		    (ttype != STT_OBJECT) && (ttype != STT_SECTION))
315 			return (tsdp);
316 	}
317 
318 	/*
319 	 * We have two global symbols, at least one of which is a data item.
320 	 * The last case where a displacement relocation can be ignored, is
321 	 * if the reference symbol is included in the target symbol.
322 	 */
323 	value = rsym->st_value;
324 	if ((rld->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
325 		value += rld->rel_raddend;
326 
327 	if ((rld->rel_roffset >= value) &&
328 	    (rld->rel_roffset < (value + rsym->st_size)))
329 		return (tsdp);
330 
331 	/*
332 	 * We have a displacement relocation that could be compromised by a
333 	 * copy relocation of one of the associated data items.
334 	 */
335 	rld->rel_flags |= FLG_REL_DISP;
336 	return (tsdp);
337 }
338 
339 void
340 ld_disp_errmsg(const char *msg, Rel_desc *rsp, Ofl_desc *ofl)
341 {
342 	Sym_desc	*sdp;
343 	const char	*str;
344 	Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
345 	Conv_inv_buf_t	inv_buf;
346 
347 	if ((sdp = disp_scansyms(ifl, rsp, 0, 1, ofl)) != 0)
348 		str = demangle(sdp->sd_name);
349 	else
350 		str = MSG_INTL(MSG_STR_UNKNOWN);
351 
352 	eprintf(ofl->ofl_lml, ERR_WARNING, msg,
353 	    conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
354 	    0, &inv_buf), ifl->ifl_name, rsp->rel_sname, str,
355 	    EC_OFF(rsp->rel_roffset));
356 }
357 
358 /*
359  * qsort(3C) comparison routine used for the disp_sortsyms().
360  */
361 static int
362 disp_qsort(const void * s1, const void * s2)
363 {
364 	Ssv_desc	*ssvp1 = ((Ssv_desc *)s1);
365 	Ssv_desc	*ssvp2 = ((Ssv_desc *)s2);
366 	Addr		val1 = ssvp1->ssv_value;
367 	Addr		val2 = ssvp2->ssv_value;
368 
369 	if (val1 > val2)
370 		return (1);
371 	if (val1 < val2)
372 		return (-1);
373 	return (0);
374 }
375 
376 /*
377  * Determine whether a displacement relocation is between a local and global
378  * symbol pair.  One symbol is used to perform the relocation, and the other
379  * is the destination offset of the relocation.
380  */
381 static uintptr_t
382 disp_inspect(Ofl_desc *ofl, Rel_desc *rld, Boolean rlocal)
383 {
384 	Is_desc		*isp = rld->rel_isdesc;
385 	Ifl_desc	*ifl = rld->rel_isdesc->is_file;
386 
387 	/*
388 	 * If the input files symbols haven't been sorted yet, do so.
389 	 */
390 	if (ifl->ifl_sortsyms == 0) {
391 		Word	ondx, nndx;
392 
393 		if ((ifl->ifl_sortsyms = libld_malloc((ifl->ifl_symscnt + 1) *
394 		    sizeof (Ssv_desc))) == 0)
395 			return (S_ERROR);
396 
397 		for (ondx = 0, nndx = 0; ondx < ifl->ifl_symscnt; ondx++) {
398 			Sym_desc	*sdp;
399 			Addr		value;
400 
401 			/*
402 			 * As symbol resolution has already occurred, various
403 			 * symbols from this object may have been satisfied
404 			 * from other objects.  Only select symbols from this
405 			 * object.  For the displacement test, we only really
406 			 * need to observe data definitions, however, later as
407 			 * part of providing warning disgnostics, relating the
408 			 * relocation offset to a symbol is desirable.  Thus,
409 			 * collect all symbols that define a memory area.
410 			 */
411 			if (((sdp = ifl->ifl_oldndx[ondx]) == 0) ||
412 			    (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
413 			    (sdp->sd_sym->st_shndx >= SHN_LORESERVE) ||
414 			    (sdp->sd_ref != REF_REL_NEED) ||
415 			    (sdp->sd_file != ifl) ||
416 			    (sdp->sd_sym->st_size == 0))
417 				continue;
418 
419 			/*
420 			 * As a further optimization for later checking, mark
421 			 * this section if this a global data definition.
422 			 */
423 			if (sdp->sd_isc && (ondx >= ifl->ifl_locscnt))
424 				sdp->sd_isc->is_flags |= FLG_IS_GDATADEF;
425 
426 			/*
427 			 * Capture the symbol.  Within relocatable objects, a
428 			 * symbols value is its offset within its associated
429 			 * section.  Add the section offset to this value to
430 			 * uniquify the symbol.
431 			 */
432 			value = sdp->sd_sym->st_value;
433 			if (sdp->sd_isc && sdp->sd_isc->is_shdr)
434 				value += sdp->sd_isc->is_shdr->sh_offset;
435 
436 			ifl->ifl_sortsyms[nndx].ssv_value = value;
437 			ifl->ifl_sortsyms[nndx].ssv_sdp = sdp;
438 			nndx++;
439 		}
440 
441 		/*
442 		 * Sort the list based on the symbols value (address).
443 		 */
444 		if ((ifl->ifl_sortcnt = nndx) != 0)
445 			qsort(ifl->ifl_sortsyms, nndx, sizeof (Ssv_desc),
446 			    &disp_qsort);
447 	}
448 
449 	/*
450 	 * If the reference symbol is local, and the section being relocated
451 	 * contains no global definitions, neither can be the target of a copy
452 	 * relocation.
453 	 */
454 	if ((rlocal == FALSE) && ((isp->is_flags & FLG_IS_GDATADEF) == 0))
455 		return (1);
456 
457 	/*
458 	 * Otherwise determine whether this relocation symbol and its offset
459 	 * could be candidates for a copy relocation.
460 	 */
461 	if (ifl->ifl_sortcnt)
462 		(void) disp_scansyms(ifl, rld, rlocal, 0, ofl);
463 	return (1);
464 }
465 
466 /*
467  * Output relocation numbers can vary considerably between building executables
468  * or shared objects (pic vs. non-pic), etc.  But, they typically aren't very
469  * large, so for these objects use a standard bucket size.  For building
470  * relocatable objects, typically there will be an output relocation for every
471  * input relocation.
472  */
473 Rel_cache *
474 ld_add_rel_cache(Ofl_desc *ofl, APlist **alpp, size_t *nextsize, size_t low,
475     size_t hi)
476 {
477 	Rel_cache	*rcp;
478 	size_t		size;
479 	APlist		*alp = *alpp;
480 
481 	/*
482 	 * If there is space available in the present cache bucket, return the
483 	 * next free entry.
484 	 */
485 	if (alp && ((rcp = alp->apl_data[aplist_nitems(alp) - 1]) != NULL) &&
486 	    (rcp->rc_free < rcp->rc_end))
487 		return (rcp);
488 
489 	/*
490 	 * Allocate a new bucket.
491 	 */
492 	if (*nextsize == 0) {
493 		if ((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) {
494 			if ((size = ofl->ofl_relocincnt) == 0)
495 				size = low;
496 			if (size > hi)
497 				*nextsize = hi;
498 			else
499 				*nextsize = low;
500 		} else
501 			*nextsize = size = hi;
502 	} else
503 		size = *nextsize;
504 
505 	size = size * sizeof (Rel_desc);
506 
507 	if (((rcp = libld_malloc(sizeof (Rel_cache) + size)) == NULL) ||
508 	    (aplist_append(alpp, rcp, AL_CNT_OFL_RELS) == NULL))
509 		return ((Rel_cache *)S_ERROR);
510 
511 	/* LINTED */
512 	rcp->rc_free = (Rel_desc *)(rcp + 1);
513 	/* LINTED */
514 	rcp->rc_end = (Rel_desc *)((char *)rcp->rc_free + size);
515 
516 	return (rcp);
517 }
518 
519 /*
520  * Add an active relocation record.
521  */
522 uintptr_t
523 ld_add_actrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl)
524 {
525 	Rel_desc	*arsp;
526 	Rel_cache	*rcp;
527 	static size_t	nextsize = 0;
528 
529 	/*
530 	 * If no relocation cache structures are available, allocate a new
531 	 * one and link it into the bucket list.
532 	 */
533 	if ((rcp = ld_add_rel_cache(ofl, &ofl->ofl_actrels, &nextsize,
534 	    REL_LAIDESCNO, REL_HAIDESCNO)) == (Rel_cache *)S_ERROR)
535 		return (S_ERROR);
536 
537 	arsp = rcp->rc_free;
538 
539 	*arsp = *rsp;
540 	arsp->rel_flags |= flags;
541 
542 	rcp->rc_free++;
543 	ofl->ofl_actrelscnt++;
544 
545 	/*
546 	 * Any GOT relocation reference requires the creation of a .got table.
547 	 * Most references to a .got require a .got entry,  which is accounted
548 	 * for with the ofl_gotcnt counter.  However, some references are
549 	 * relative to the .got table, but require no .got entry.  This test
550 	 * insures a .got is created regardless of the type of reference.
551 	 */
552 	if (IS_GOT_REQUIRED(arsp->rel_rtype))
553 		ofl->ofl_flags |= FLG_OF_BLDGOT;
554 
555 	/*
556 	 * If this is a displacement relocation generate a warning.
557 	 */
558 	if (arsp->rel_flags & FLG_REL_DISP) {
559 		ofl->ofl_dtflags_1 |= DF_1_DISPRELDNE;
560 
561 		if (ofl->ofl_flags & FLG_OF_VERBOSE)
562 			ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl);
563 	}
564 
565 	DBG_CALL(Dbg_reloc_ars_entry(ofl->ofl_lml, ELF_DBG_LD,
566 	    arsp->rel_isdesc->is_shdr->sh_type, ld_targ.t_m.m_mach, arsp));
567 	return (1);
568 }
569 
570 /*
571  * In the platform specific machrel.XXX.c files, we sometimes write
572  * a value directly into the got/plt. These function can be used when
573  * the running linker has the opposite byte order of the object being
574  * produced.
575  */
576 Word
577 ld_bswap_Word(Word v)
578 {
579 	return (BSWAP_WORD(v));
580 }
581 
582 
583 Xword
584 ld_bswap_Xword(Xword v)
585 {
586 	return (BSWAP_XWORD(v));
587 }
588 
589 
590 uintptr_t
591 ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
592 {
593 	Sym_desc	*sdp = rsp->rel_sym;
594 	ofl_flag_t	flags = ofl->ofl_flags;
595 	Gotndx		*gnp;
596 
597 	/*
598 	 * If this is the first time we've seen this symbol in a GOT
599 	 * relocation we need to assign it a GOT token.  Once we've got
600 	 * all of the GOT's assigned we can assign the actual indexes.
601 	 */
602 	if ((gnp = (*ld_targ.t_mr.mr_find_got_ndx)(sdp->sd_GOTndxs,
603 	    GOT_REF_GENERIC, ofl, rsp)) == 0) {
604 		Word	rtype = rsp->rel_rtype;
605 
606 		if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), NULL,
607 		    GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
608 			return (S_ERROR);
609 
610 		/*
611 		 * Now we initialize the GOT table entry.
612 		 *
613 		 * Pseudo code to describe the the decisions below:
614 		 *
615 		 * If (local)
616 		 * then
617 		 *	enter symbol value in GOT table entry
618 		 *	if (Shared Object)
619 		 *	then
620 		 *		create Relative relocation against symbol
621 		 *	fi
622 		 * else
623 		 *	clear GOT table entry
624 		 *	create a GLOB_DAT relocation against symbol
625 		 * fi
626 		 */
627 		if (local == TRUE) {
628 			if (flags & FLG_OF_SHAROBJ) {
629 				if (ld_add_actrel((FLG_REL_GOT | FLG_REL_GOTCL),
630 				    rsp, ofl) == S_ERROR)
631 					return (S_ERROR);
632 
633 				/*
634 				 * Add a RELATIVE relocation if this is
635 				 * anything but a ABS symbol.
636 				 */
637 				if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
638 				    (sdp->sd_sym->st_shndx != SHN_ABS)) ||
639 				    (sdp->sd_aux && sdp->sd_aux->sa_symspec)) {
640 					rsp->rel_rtype =
641 					    ld_targ.t_m.m_r_relative;
642 					if ((*ld_targ.t_mr.mr_add_outrel)
643 					    ((FLG_REL_GOT | FLG_REL_ADVAL), rsp,
644 					    ofl) == S_ERROR)
645 						return (S_ERROR);
646 					rsp->rel_rtype = rtype;
647 				}
648 			} else {
649 				if (ld_add_actrel(FLG_REL_GOT, rsp,
650 				    ofl) == S_ERROR)
651 					return (S_ERROR);
652 			}
653 		} else {
654 			rsp->rel_rtype = ld_targ.t_m.m_r_glob_dat;
655 			if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_GOT,
656 			    rsp, ofl) == S_ERROR)
657 				return (S_ERROR);
658 			rsp->rel_rtype = rtype;
659 		}
660 	} else {
661 		if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
662 		    GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
663 			return (S_ERROR);
664 	}
665 
666 	/*
667 	 * Perform relocation to GOT table entry.
668 	 */
669 	return (ld_add_actrel(NULL, rsp, ofl));
670 }
671 
672 /*
673  * Perform relocations for PLT's
674  */
675 uintptr_t
676 ld_reloc_plt(Rel_desc *rsp, Ofl_desc *ofl)
677 {
678 	Sym_desc	*sdp = rsp->rel_sym;
679 
680 	switch (ld_targ.t_m.m_mach) {
681 	case EM_AMD64:
682 		/*
683 		 * AMD64 TLS code sequences do not use a unique TLS
684 		 * relocation to reference the __tls_get_addr() function call.
685 		 */
686 		if ((ofl->ofl_flags & FLG_OF_EXEC) &&
687 		    (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) ==
688 		    0))
689 			return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
690 		break;
691 
692 	case EM_386:
693 		/*
694 		 * GNUC IA32 TLS code sequences do not use a unique TLS
695 		 * relocation to reference the ___tls_get_addr() function call.
696 		 */
697 		if ((ofl->ofl_flags & FLG_OF_EXEC) &&
698 		    (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) ==
699 		    0))
700 			return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
701 		break;
702 	}
703 
704 	/*
705 	 * if (not PLT yet assigned)
706 	 * then
707 	 *	assign PLT index to symbol
708 	 *	build output JMP_SLOT relocation
709 	 * fi
710 	 */
711 	if (sdp->sd_aux->sa_PLTndx == 0) {
712 		Word	ortype = rsp->rel_rtype;
713 
714 		(*ld_targ.t_mr.mr_assign_plt_ndx)(sdp, ofl);
715 
716 		/*
717 		 * If this symbol is binding to a LAZYLOADED object then
718 		 * set the LAZYLD symbol flag.
719 		 */
720 		if ((sdp->sd_aux->sa_bindto &&
721 		    (sdp->sd_aux->sa_bindto->ifl_flags & FLG_IF_LAZYLD)) ||
722 		    (sdp->sd_file &&
723 		    (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD)))
724 			sdp->sd_flags |= FLG_SY_LAZYLD;
725 
726 		rsp->rel_rtype = ld_targ.t_m.m_r_jmp_slot;
727 		if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_PLT, rsp, ofl) ==
728 		    S_ERROR)
729 			return (S_ERROR);
730 		rsp->rel_rtype = ortype;
731 	}
732 
733 	/*
734 	 * Perform relocation to PLT table entry.
735 	 */
736 	if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
737 	    IS_ADD_RELATIVE(rsp->rel_rtype)) {
738 		Word	ortype	= rsp->rel_rtype;
739 
740 		rsp->rel_rtype = ld_targ.t_m.m_r_relative;
741 		if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_ADVAL, rsp, ofl) ==
742 		    S_ERROR)
743 			return (S_ERROR);
744 		rsp->rel_rtype = ortype;
745 		return (1);
746 	} else
747 		return (ld_add_actrel(NULL, rsp, ofl));
748 }
749 
750 /*
751  * process GLOBAL undefined and ref_dyn_need symbols.
752  */
753 static uintptr_t
754 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl)
755 {
756 	Sym_desc	*_sdp, *sdp = rsp->rel_sym;
757 	Sym_aux		*sap = sdp->sd_aux;
758 	Sym		*sym = sdp->sd_sym;
759 	Addr		stval;
760 
761 	/*
762 	 * Reference is to a function so simply create a plt entry for it.
763 	 */
764 	if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
765 		return (ld_reloc_plt(rsp, ofl));
766 
767 	/*
768 	 * Catch absolutes - these may cause a text relocation.
769 	 */
770 	if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sym->st_shndx == SHN_ABS)) {
771 		if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0)
772 			return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
773 
774 		/*
775 		 * If -zabsexec is set then promote the ABSOLUTE symbol to
776 		 * current the current object and perform the relocation now.
777 		 */
778 		sdp->sd_ref = REF_REL_NEED;
779 		return (ld_add_actrel(NULL, rsp, ofl));
780 	}
781 
782 	/*
783 	 * If the relocation is against a writable section simply compute the
784 	 * necessary output relocation.  As an optimization, if the symbol has
785 	 * already been transformed into a copy relocation then we can perform
786 	 * the relocation directly (copy relocations should only be generated
787 	 * for references from the text segment and these relocations are
788 	 * normally carried out before we get to the data segment relocations).
789 	 */
790 	if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) &&
791 	    (rsp->rel_osdesc->os_shdr->sh_flags & SHF_WRITE)) {
792 		if (sdp->sd_flags & FLG_SY_MVTOCOMM)
793 			return (ld_add_actrel(NULL, rsp, ofl));
794 		else
795 			return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
796 	}
797 
798 	/*
799 	 * If the reference isn't to an object (normally because a .type
800 	 * directive hasn't defined in some assembler source), then simply apply
801 	 * a generic relocation (this has a tendency to result in text
802 	 * relocations).
803 	 */
804 	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) {
805 		Conv_inv_buf_t inv_buf;
806 
807 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
808 		    conv_sym_info_type(sdp->sd_file->ifl_ehdr->e_machine,
809 		    ELF_ST_TYPE(sym->st_info), 0, &inv_buf),
810 		    rsp->rel_isdesc->is_file->ifl_name,
811 		    demangle(rsp->rel_sname), sdp->sd_file->ifl_name);
812 		return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
813 	}
814 
815 	/*
816 	 * Prepare for generating a copy relocation.
817 	 *
818 	 * If this symbol is one of an alias pair, we need to insure both
819 	 * symbols become part of the output (the strong symbol will be used to
820 	 * maintain the symbols state).  And, if we did raise the precedence of
821 	 * a symbol we need to check and see if this is a weak symbol.  If it is
822 	 * we want to use it's strong counter part.
823 	 *
824 	 * The results of this logic should be:
825 	 *	rel_usym: assigned to strong
826 	 *	 rel_sym: assigned to symbol to perform
827 	 *		  copy_reloc against (weak or strong).
828 	 */
829 	if (sap->sa_linkndx) {
830 		_sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
831 
832 		if (_sdp->sd_ref < sdp->sd_ref) {
833 			_sdp->sd_ref = sdp->sd_ref;
834 			_sdp->sd_flags |= FLG_SY_REFRSD;
835 
836 			/*
837 			 * As we're going to replicate a symbol from a shared
838 			 * object, retain its correct binding status.
839 			 */
840 			if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL)
841 				_sdp->sd_flags |= FLG_SY_GLOBREF;
842 
843 		} else if (_sdp->sd_ref > sdp->sd_ref) {
844 			sdp->sd_ref = _sdp->sd_ref;
845 			sdp->sd_flags |= FLG_SY_REFRSD;
846 
847 			/*
848 			 * As we're going to replicate a symbol from a shared
849 			 * object, retain its correct binding status.
850 			 */
851 			if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL)
852 				sdp->sd_flags |= FLG_SY_GLOBREF;
853 		}
854 
855 		/*
856 		 * If this is a weak symbol then we want to move the strong
857 		 * symbol into local .bss.  If there is a copy_reloc to be
858 		 * performed, that should still occur against the WEAK symbol.
859 		 */
860 		if ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
861 		    (sdp->sd_flags & FLG_SY_WEAKDEF))
862 			rsp->rel_usym = _sdp;
863 	} else
864 		_sdp = 0;
865 
866 	/*
867 	 * If the reference is to an object then allocate space for the object
868 	 * within the executables .bss.  Relocations will now be performed from
869 	 * this new location.  If the original shared objects data is
870 	 * initialized, then generate a copy relocation that will copy the data
871 	 * to the executables .bss at runtime.
872 	 */
873 	if (!(rsp->rel_usym->sd_flags & FLG_SY_MVTOCOMM)) {
874 		Word		rtype = rsp->rel_rtype;
875 		Copy_rel	cr;
876 
877 		/*
878 		 * Indicate that the symbol(s) against which we're relocating
879 		 * have been moved to the executables common.  Also, insure that
880 		 * the symbol(s) remain marked as global, as the shared object
881 		 * from which they are copied must be able to relocate to the
882 		 * new common location within the executable.
883 		 *
884 		 * Note that even though a new symbol has been generated in the
885 		 * output files' .bss, the symbol must remain REF_DYN_NEED and
886 		 * not be promoted to REF_REL_NEED.  sym_validate() still needs
887 		 * to carry out a number of checks against the symbols binding
888 		 * that are triggered by the REF_DYN_NEED state.
889 		 */
890 		sdp->sd_flags |= FLG_SY_MVTOCOMM;
891 		sdp->sd_flags1 |= (FLG_SY1_DEFAULT | FLG_SY1_EXPDEF);
892 		sdp->sd_flags1 &= ~MSK_SY1_LOCAL;
893 		sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
894 		if (_sdp) {
895 			_sdp->sd_flags |= FLG_SY_MVTOCOMM;
896 			_sdp->sd_flags1 |= (FLG_SY1_DEFAULT | FLG_SY1_EXPDEF);
897 			_sdp->sd_flags1 &= ~MSK_SY1_LOCAL;
898 			_sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
899 
900 			/*
901 			 * Make sure the symbol has a reference in case of any
902 			 * error diagnostics against it (perhaps this belongs
903 			 * to a version that isn't allowable for this build).
904 			 * The resulting diagnostic (see sym_undef_entry())
905 			 * might seem a little bogus, as the symbol hasn't
906 			 * really been referenced by this file, but has been
907 			 * promoted as a consequence of its alias reference.
908 			 */
909 			if (!(_sdp->sd_aux->sa_rfile))
910 				_sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile;
911 		}
912 
913 		/*
914 		 * Assign the symbol to the bss and insure sufficient alignment
915 		 * (we don't know the real alignment so we have to make the
916 		 * worst case guess).
917 		 */
918 		_sdp = rsp->rel_usym;
919 		stval = _sdp->sd_sym->st_value;
920 		if (ld_sym_copy(_sdp) == S_ERROR)
921 			return (S_ERROR);
922 		_sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON;
923 		_sdp->sd_flags |= FLG_SY_SPECSEC;
924 		_sdp->sd_sym->st_value =
925 		    (_sdp->sd_sym->st_size < (ld_targ.t_m.m_word_align * 2)) ?
926 		    ld_targ.t_m.m_word_align : ld_targ.t_m.m_word_align * 2;
927 
928 		/*
929 		 * Whether or not the symbol references initialized data we
930 		 * generate a copy relocation - this differs from the past
931 		 * where we would not create the COPY_RELOC if we were binding
932 		 * against .bss.  This is done for *two* reasons.
933 		 *
934 		 *  -	If the symbol in the shared object changes to a
935 		 *	initialized data - we need the COPY to pick it up.
936 		 *  -	Without the COPY RELOC we can't tell that the symbol
937 		 *	from the COPY'd object has been moved and all bindings
938 		 *	to it should bind here.
939 		 *
940 		 * Keep this symbol in the copy relocation list to check the
941 		 * validity later.
942 		 */
943 		cr.c_sdp = _sdp;
944 		cr.c_val = stval;
945 		if (alist_append(&ofl->ofl_copyrels, &cr, sizeof (Copy_rel),
946 		    AL_CNT_OFL_COPYRELS) == NULL)
947 			return (S_ERROR);
948 
949 		rsp->rel_rtype = ld_targ.t_m.m_r_copy;
950 		if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_BSS, rsp, ofl) ==
951 		    S_ERROR)
952 			return (S_ERROR);
953 		rsp->rel_rtype = rtype;
954 
955 		/*
956 		 * If this symbol is a protected symbol, warn it.
957 		 */
958 		if (_sdp->sd_flags & FLG_SY_PROT) {
959 			Conv_inv_buf_t inv_buf;
960 
961 			eprintf(ofl->ofl_lml, ERR_WARNING,
962 			    MSG_INTL(MSG_REL_COPY),
963 			    conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine,
964 			    ld_targ.t_m.m_r_copy, 0, &inv_buf),
965 			    _sdp->sd_file->ifl_name, _sdp->sd_name);
966 		}
967 		DBG_CALL(Dbg_syms_reloc(ofl, sdp));
968 	}
969 	return (ld_add_actrel(NULL, rsp, ofl));
970 }
971 
972 /*
973  * All relocations should have been handled by the other routines.  This
974  * routine is here as a catch all, if we do enter it we've goofed - but
975  * we'll try and to the best we can.
976  */
977 static uintptr_t
978 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl)
979 {
980 	Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
981 	Conv_inv_buf_t	inv_buf;
982 
983 	eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
984 	    conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
985 	    0, &inv_buf), ifl->ifl_name, demangle(rsp->rel_sname));
986 
987 	/*
988 	 * If building a shared object then put the relocation off
989 	 * until runtime.
990 	 */
991 	if (ofl->ofl_flags & FLG_OF_SHAROBJ)
992 		return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
993 
994 	/*
995 	 * Otherwise process relocation now.
996 	 */
997 	return (ld_add_actrel(NULL, rsp, ofl));
998 }
999 
1000 /*
1001  * Process relocations when building a relocatable object.  Typically, there
1002  * aren't many relocations that can be caught at this point, most are simply
1003  * passed through to the output relocatable object.
1004  */
1005 static uintptr_t
1006 reloc_relobj(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1007 {
1008 	Word		rtype = rsp->rel_rtype;
1009 	Sym_desc	*sdp = rsp->rel_sym;
1010 	Is_desc		*isp = rsp->rel_isdesc;
1011 	Word		oflags = NULL;
1012 
1013 	/*
1014 	 * Determine if we can do any relocations at this point.  We can if:
1015 	 *
1016 	 *	this is local_symbol and a non-GOT relocation, and
1017 	 *	the relocation is pc-relative, and
1018 	 *	the relocation is against a symbol in same section
1019 	 */
1020 	if (local && !IS_GOT_RELATIVE(rtype) &&
1021 	    !IS_GOT_BASED(rtype) && !IS_GOT_PC(rtype) &&
1022 	    IS_PC_RELATIVE(rtype) &&
1023 	    ((sdp->sd_isc) && (sdp->sd_isc->is_osdesc == isp->is_osdesc)))
1024 		return (ld_add_actrel(NULL, rsp, ofl));
1025 
1026 	/*
1027 	 * If -zredlocsym is in effect, translate all local symbol relocations
1028 	 * to be against section symbols, since section symbols are the only
1029 	 * local symbols which will be added to the .symtab.
1030 	 */
1031 	if (local && (((ofl->ofl_flags & FLG_OF_REDLSYM) &&
1032 	    (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL)) ||
1033 	    ((sdp->sd_flags1 & FLG_SY1_ELIM) &&
1034 	    (ofl->ofl_flags & FLG_OF_PROCRED)))) {
1035 		/*
1036 		 * But if this is PIC code, don't allow it for now.
1037 		 */
1038 		if (IS_GOT_RELATIVE(rsp->rel_rtype)) {
1039 			Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
1040 			Conv_inv_buf_t inv_buf;
1041 
1042 			eprintf(ofl->ofl_lml, ERR_FATAL,
1043 			    MSG_INTL(MSG_REL_PICREDLOC),
1044 			    demangle(rsp->rel_sname), ifl->ifl_name,
1045 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
1046 			    rsp->rel_rtype, 0, &inv_buf));
1047 			return (S_ERROR);
1048 		}
1049 
1050 		/*
1051 		 * Indicate that this relocation should be processed the same
1052 		 * as a section symbol.  For RELA, indicate that the addend
1053 		 * also needs to be applied to this relocation.
1054 		 */
1055 		if ((rsp->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
1056 			oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL;
1057 		else
1058 			oflags = FLG_REL_SCNNDX;
1059 	}
1060 
1061 	if ((rsp->rel_flags & FLG_REL_RELA) == 0) {
1062 		/*
1063 		 * Intel (Rel) relocations do not contain an addend.  Any
1064 		 * addend is contained within the file at the location
1065 		 * identified by the relocation offset.  Therefore, if we're
1066 		 * processing a section symbol, or a -zredlocsym relocation
1067 		 * (that basically transforms a local symbol reference into
1068 		 * a section reference), perform an active relocation to
1069 		 * propagate any addend.
1070 		 */
1071 		if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) ||
1072 		    (oflags == FLG_REL_SCNNDX))
1073 			if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR)
1074 				return (S_ERROR);
1075 	}
1076 	return ((*ld_targ.t_mr.mr_add_outrel)(oflags, rsp, ofl));
1077 }
1078 
1079 /*
1080  * Perform any generic TLS validations before passing control to machine
1081  * specific routines.  At this point we know we are dealing with an executable
1082  * or shared object - relocatable objects have already been processed.
1083  */
1084 static uintptr_t
1085 reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1086 {
1087 	Word		rtype = rsp->rel_rtype;
1088 	ofl_flag_t	flags = ofl->ofl_flags;
1089 	Ifl_desc	*ifl = rsp->rel_isdesc->is_file;
1090 	Half		mach = ifl->ifl_ehdr->e_machine;
1091 	Sym_desc	*sdp = rsp->rel_sym;
1092 	unsigned char	type;
1093 	Conv_inv_buf_t	inv_buf1, inv_buf2;
1094 
1095 	/*
1096 	 * All TLS relocations are illegal in a static executable.
1097 	 */
1098 	if ((flags & (FLG_OF_STATIC | FLG_OF_EXEC)) ==
1099 	    (FLG_OF_STATIC | FLG_OF_EXEC)) {
1100 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
1101 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1102 		    demangle(rsp->rel_sname));
1103 		return (S_ERROR);
1104 	}
1105 
1106 	/*
1107 	 * Any TLS relocation must be against a STT_TLS symbol, all others
1108 	 * are illegal.
1109 	 */
1110 	if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) {
1111 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
1112 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1113 		    demangle(rsp->rel_sname),
1114 		    conv_sym_info_type(mach, type, 0, &inv_buf2));
1115 		return (S_ERROR);
1116 	}
1117 
1118 	/*
1119 	 * A dynamic executable can not use the LD or LE reference models to
1120 	 * reference an external symbol.  A shared object can not use the LD
1121 	 * reference model to reference an external symbol.
1122 	 */
1123 	if (!local && (IS_TLS_LD(rtype) ||
1124 	    ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) {
1125 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
1126 		    conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1127 		    demangle(rsp->rel_sname), sdp->sd_file->ifl_name);
1128 		return (S_ERROR);
1129 	}
1130 
1131 	/*
1132 	 * The TLS LE model is only allowed for dynamic executables.  The TLS IE
1133 	 * model is allowed for shared objects, but this model has restrictions.
1134 	 * This model can only be used freely in dependencies that are loaded
1135 	 * immediately as part of process initialization.  However, during the
1136 	 * initial runtime handshake with libc that establishes the thread
1137 	 * pointer, a small backup TLS reservation is created.  This area can
1138 	 * be used by objects that are loaded after threads are initialized.
1139 	 * However, this area is limited in size and may have already been
1140 	 * used.  This area is intended for specialized applications, and does
1141 	 * not provide the degree of flexibility dynamic TLS can offer.  Under
1142 	 * -z verbose indicate this restriction to the user.
1143 	 */
1144 	if ((flags & FLG_OF_EXEC) == 0) {
1145 		if (IS_TLS_LE(rtype)) {
1146 			eprintf(ofl->ofl_lml, ERR_FATAL,
1147 			    MSG_INTL(MSG_REL_TLSLE),
1148 			    conv_reloc_type(mach, rtype, 0, &inv_buf1),
1149 			    ifl->ifl_name, demangle(rsp->rel_sname));
1150 			return (S_ERROR);
1151 
1152 		} else if ((IS_TLS_IE(rtype)) &&
1153 		    (flags & FLG_OF_VERBOSE)) {
1154 			eprintf(ofl->ofl_lml, ERR_WARNING,
1155 			    MSG_INTL(MSG_REL_TLSIE),
1156 			    conv_reloc_type(mach, rtype, 0, &inv_buf1),
1157 			    ifl->ifl_name, demangle(rsp->rel_sname));
1158 		}
1159 	}
1160 
1161 	return ((*ld_targ.t_mr.mr_reloc_TLS)(local, rsp, ofl));
1162 }
1163 
1164 uintptr_t
1165 ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
1166     const char *isname, Word isscnndx)
1167 {
1168 	Word		rtype = reld->rel_rtype;
1169 	ofl_flag_t	flags = ofl->ofl_flags;
1170 	Sym_desc	*sdp = reld->rel_sym;
1171 	Sym_aux		*sap;
1172 	Boolean		local;
1173 	Conv_inv_buf_t	inv_buf;
1174 
1175 	DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, ld_targ.t_m.m_mach,
1176 	    ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname, isscnndx,
1177 	    reld->rel_sname));
1178 
1179 	/*
1180 	 * Indicate this symbol is being used for relocation and therefore must
1181 	 * have its output address updated accordingly (refer to update_osym()).
1182 	 */
1183 	sdp->sd_flags |= FLG_SY_UPREQD;
1184 
1185 	/*
1186 	 * Indicate the section this symbol is defined in has been referenced,
1187 	 * therefor it *is not* a candidate for elimination.
1188 	 */
1189 	if (sdp->sd_isc) {
1190 		sdp->sd_isc->is_flags |= FLG_IS_SECTREF;
1191 		sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF;
1192 	}
1193 
1194 	reld->rel_usym = sdp;
1195 
1196 	/*
1197 	 * Determine if this symbol is actually an alias to another symbol.  If
1198 	 * so, and the alias is not REF_DYN_SEEN, set rel_usym to point to the
1199 	 * weak symbols strong counter-part.  The one exception is if the
1200 	 * FLG_SY_MVTOCOMM flag is set on the weak symbol.  If this is the case,
1201 	 * the strong is only here because of its promotion, and the weak symbol
1202 	 * should still be used for the relocation reference (see reloc_exec()).
1203 	 */
1204 	sap = sdp->sd_aux;
1205 	if (sap && sap->sa_linkndx &&
1206 	    ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1207 	    (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1208 	    (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) {
1209 		Sym_desc *	_sdp;
1210 
1211 		_sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1212 		if (_sdp->sd_ref != REF_DYN_SEEN)
1213 			reld->rel_usym = _sdp;
1214 	}
1215 
1216 	/*
1217 	 * Determine whether this symbol should be bound locally or not.
1218 	 * Symbols are bound locally if one of the following is true:
1219 	 *
1220 	 *  o	the symbol is of type STB_LOCAL.
1221 	 *
1222 	 *  o	the output image is not a relocatable object and the relocation
1223 	 *	is relative to the .got.
1224 	 *
1225 	 *  o	the section being relocated is of type SHT_SUNW_dof.  These
1226 	 *	sections must be bound to the functions in the containing
1227 	 *	object and can not be interposed upon.
1228 	 *
1229 	 *  o	the symbol has been reduced (scoped to a local or symbolic) and
1230 	 *	reductions are being processed.
1231 	 *
1232 	 *  o	the -Bsymbolic flag is in use when building a shared object,
1233 	 *	and the symbol hasn't explicitly been defined as nodirect.
1234 	 *
1235 	 *  o	an executable (fixed address) is being created, and the symbol
1236 	 *	is defined in the executable.
1237 	 *
1238 	 *  o	the relocation is against a segment which will not be loaded
1239 	 *	into memory.  In this case, the relocation must be resolved
1240 	 *	now, as ld.so.1 can not process relocations against unmapped
1241 	 *	segments.
1242 	 */
1243 	local = FALSE;
1244 	if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1245 		local = TRUE;
1246 	} else if (!(reld->rel_flags & FLG_REL_LOAD)) {
1247 		local = TRUE;
1248 	} else if (sdp->sd_sym->st_shndx != SHN_UNDEF) {
1249 		if (reld->rel_isdesc &&
1250 		    reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) {
1251 			local = TRUE;
1252 		} else if (!(flags & FLG_OF_RELOBJ) &&
1253 		    (IS_LOCALBND(rtype) ||
1254 		    IS_SEG_RELATIVE(rtype))) {
1255 			local = TRUE;
1256 		} else if (sdp->sd_ref == REF_REL_NEED) {
1257 			/*
1258 			 * Global symbols may have been individually reduced in
1259 			 * scope.  If the whole object is to be self contained,
1260 			 * such as when generating an executable or a symbolic
1261 			 * shared object, make sure all relocation symbol
1262 			 * references (sections too) are treated locally.  Note,
1263 			 * explicit no-direct symbols should not be bound to
1264 			 * locally.
1265 			 */
1266 			if ((sdp->sd_flags1 &
1267 			    (FLG_SY1_HIDDEN | FLG_SY1_PROTECT)))
1268 				local = TRUE;
1269 			else if ((flags & FLG_OF_EXEC) ||
1270 			    ((flags & FLG_OF_SYMBOLIC) &&
1271 			    ((sdp->sd_flags1 & FLG_SY1_NDIR) == 0)))
1272 				local = TRUE;
1273 		}
1274 	}
1275 
1276 	/*
1277 	 * If this is a PC_RELATIVE relocation, the relocation could be
1278 	 * compromised if the relocated address is later used as a copy
1279 	 * relocated symbol (PSARC 1999/636, bugid 4187211).  Scan the input
1280 	 * files symbol table to cross reference this relocation offset.
1281 	 */
1282 	if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
1283 	    IS_PC_RELATIVE(rtype) &&
1284 	    (IS_GOT_PC(rtype) == 0) &&
1285 	    (IS_PLT(rtype) == 0)) {
1286 		if (disp_inspect(ofl, reld, local) == S_ERROR)
1287 			return (S_ERROR);
1288 	}
1289 
1290 	/*
1291 	 * GOT based relocations must bind to the object being built - since
1292 	 * they are relevant to the current GOT.  If not building a relocatable
1293 	 * object - give a appropriate error message.
1294 	 */
1295 	if (!local && !(flags & FLG_OF_RELOBJ) &&
1296 	    IS_GOT_BASED(rtype)) {
1297 		Ifl_desc	*ifl = reld->rel_isdesc->is_file;
1298 
1299 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
1300 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1301 		    0, &inv_buf), ifl->ifl_name, demangle(sdp->sd_name));
1302 		return (S_ERROR);
1303 	}
1304 
1305 	/*
1306 	 * TLS symbols can only have TLS relocations.
1307 	 */
1308 	if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) &&
1309 	    (IS_TLS_INS(rtype) == 0)) {
1310 		/*
1311 		 * The above test is relaxed if the target section is
1312 		 * non-allocable.
1313 		 */
1314 		if (reld->rel_osdesc->os_shdr->sh_flags & SHF_ALLOC) {
1315 			Ifl_desc	*ifl = reld->rel_isdesc->is_file;
1316 
1317 			eprintf(ofl->ofl_lml, ERR_FATAL,
1318 			    MSG_INTL(MSG_REL_BADTLS),
1319 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
1320 			    rtype, 0, &inv_buf), ifl->ifl_name,
1321 			    demangle(sdp->sd_name));
1322 			return (S_ERROR);
1323 		}
1324 	}
1325 
1326 	/*
1327 	 * Select the relocation to perform.
1328 	 */
1329 	if (IS_REGISTER(rtype)) {
1330 		if (ld_targ.t_mr.mr_reloc_register == NULL) {
1331 			eprintf(ofl->ofl_lml, ERR_FATAL,
1332 			    MSG_INTL(MSG_REL_NOREG));
1333 			return (S_ERROR);
1334 		}
1335 		return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1336 	}
1337 
1338 	if (flags & FLG_OF_RELOBJ)
1339 		return (reloc_relobj(local, reld, ofl));
1340 
1341 	if (IS_TLS_INS(rtype))
1342 		return (reloc_TLS(local, reld, ofl));
1343 
1344 	if (IS_GOT_OPINS(rtype)) {
1345 		if (ld_targ.t_mr.mr_reloc_GOTOP == NULL) {
1346 			assert(0);
1347 			return (S_ERROR);
1348 		}
1349 		return ((*ld_targ.t_mr.mr_reloc_GOTOP)(local, reld, ofl));
1350 	}
1351 
1352 	if (IS_GOT_RELATIVE(rtype))
1353 		return (ld_reloc_GOT_relative(local, reld, ofl));
1354 
1355 	if (local)
1356 		return ((*ld_targ.t_mr.mr_reloc_local)(reld, ofl));
1357 
1358 	if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0))
1359 		return (ld_reloc_plt(reld, ofl));
1360 
1361 	if ((sdp->sd_ref == REF_REL_NEED) ||
1362 	    (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) ||
1363 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE))
1364 		return ((*ld_targ.t_mr.mr_add_outrel)(NULL, reld, ofl));
1365 
1366 	if (sdp->sd_ref == REF_DYN_NEED)
1367 		return (reloc_exec(reld, ofl));
1368 
1369 	/*
1370 	 * IS_NOT_REL(rtype)
1371 	 */
1372 	return (reloc_generic(reld, ofl));
1373 }
1374 
1375 /*
1376  * Given a relocation that references a local symbol from a discarded COMDAT
1377  * section, replace the symbol with the corresponding symbol from the section
1378  * that was kept.
1379  *
1380  * entry:
1381  *	reld - Relocation
1382  *	sdp - Symbol to be replaced. Must be a local symbol (STB_LOCAL).
1383  *	reject - Address of variable to receive rejection code
1384  *		if no replacement symbol is found.
1385  *
1386  * exit:
1387  *	Returns address of replacement symbol descriptor if one was
1388  *	found, and NULL otherwise. The result is also cached in
1389  *	ofl->ofl_sr_cache as an optimization to speed following calls
1390  *	for the same value of sdp.
1391  *
1392  *	On success (non-NULL result), *reject is set to RLXREL_REJ_NONE.
1393  *	On failure (NULL result), *reject is filled in with a code
1394  *	describing the underlying reason.
1395  *
1396  * note:
1397  *	The word "COMDAT" is used to refer to actual COMDAT sections, COMDAT
1398  *	groups tied together with an SHF_GROUP section, and .gnu.linkonce
1399  *	sections which provide a simplified COMDAT requirement.  COMDAT
1400  *	sections are identified with the FLG_IS_COMDAT section flag.
1401  *
1402  *	In principle, this sort of sloppy relocation remapping is
1403  *	a questionable practice. All self-referential sections should
1404  *	be in a common SHF_GROUP so that they are all kept or removed
1405  *	together. The problem is that there is no way to ensure that the
1406  *	two sections are similar enough that the replacement section will
1407  *	really supply the correct information. However, we see a couple of
1408  *	situations where it is useful to do this: (1) Older Sun C compilers
1409  *	generated DWARF sections that would refer to one of the COMDAT
1410  *	sections, and (2) gcc, when its GNU linkonce COMDAT feature is enabled.
1411  *	It turns out that the GNU ld does these sloppy remappings.
1412  *
1413  *	The GNU ld takes an approach that hard wires special section
1414  *	names and treats them specially. We avoid that practice and
1415  *	try to get the necessary work done relying only on the ELF
1416  *	attributes of the sections and symbols involved. This means
1417  *	that our heuristic is somewhat different than theirs, but the
1418  *	end result is close enough to solve the same problem.
1419  *
1420  *	gcc is in the process of converting to SHF_GROUP. This will
1421  *	eventually phase out the need for sloppy relocations, and
1422  *	then this logic won't be needed. In the meantime, relaxed relocation
1423  *	processing allows us to interoperate.
1424  */
1425 static Sym_desc *
1426 sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp,
1427     Rlxrel_rej *reject)
1428 {
1429 	Is_desc		*rep_isp;
1430 	Sym		*sym, *rep_sym;
1431 	Is_desc		*isp;
1432 	Ifl_desc	*ifl;
1433 	Conv_inv_buf_t	inv_buf;
1434 	Word		scnndx, symscnt;
1435 	Sym_desc	**oldndx, *rep_sdp;
1436 	const char	*is_name;
1437 
1438 
1439 	/*
1440 	 * Sloppy relocations are never applied to .eh_frame or
1441 	 * .gcc_except_table sections. The entries in these sections
1442 	 * for discarded sections are better left uninitialized.
1443 	 *
1444 	 * We match these sections by name, because on most platforms they
1445 	 * are SHT_PROGBITS, and cannot be identified otherwise. On amd64
1446 	 * architectures, .eh_frame is SHT_AMD64_UNWIND, but that is ambiguous
1447 	 * (.eh_frame_hdr is also SHT_AMD64_UNWIND), so we still match it by
1448 	 * name.
1449 	 */
1450 	is_name = reld->rel_isdesc->is_name;
1451 	if (((is_name[1] == 'e') &&
1452 	    (strcmp(is_name, MSG_ORIG(MSG_SCN_EHFRAME)) == 0)) ||
1453 	    ((is_name[1] == 'g') &&
1454 	    (strcmp(is_name, MSG_ORIG(MSG_SCN_GCC_X_TBL)) == 0))) {
1455 		*reject = RLXREL_REJ_TARGET;
1456 		return (NULL);
1457 	}
1458 
1459 	/*
1460 	 * If we looked up the same symbol on the previous call, we can
1461 	 * return the cached value.
1462 	 */
1463 	if (sdp == ofl->ofl_sr_cache.sr_osdp) {
1464 		*reject = ofl->ofl_sr_cache.sr_rej;
1465 		return (ofl->ofl_sr_cache.sr_rsdp);
1466 	}
1467 
1468 	ofl->ofl_sr_cache.sr_osdp = sdp;
1469 	sym = sdp->sd_sym;
1470 	isp = sdp->sd_isc;
1471 	ifl = sdp->sd_file;
1472 
1473 	/*
1474 	 * When a COMDAT section is discarded in favor of another COMDAT
1475 	 * section, the replacement is recorded in its section descriptor
1476 	 * (is_comdatkeep). We must validate the replacement before using
1477 	 * it. The replacement section must:
1478 	 *	- Not have been discarded
1479 	 *	- Have the same size (*)
1480 	 *	- Have the same section type
1481 	 *	- Have the same SHF_GROUP flag setting (either on or off)
1482 	 *	- Must be a COMDAT section of one form or the other.
1483 	 *
1484 	 * (*) One might imagine that the replacement section could be
1485 	 * larger than the original, rather than the exact size. However,
1486 	 * we have verified that this is the same policy used by the GNU
1487 	 * ld. If the sections are not the same size, the chance of them
1488 	 * being interchangeable drops significantly.
1489 	 */
1490 	if (((rep_isp = isp->is_comdatkeep) == NULL) ||
1491 	    ((rep_isp->is_flags & FLG_IS_DISCARD) != 0) ||
1492 	    ((rep_isp->is_flags & FLG_IS_COMDAT) == 0) ||
1493 	    (isp->is_indata->d_size != rep_isp->is_indata->d_size) ||
1494 	    (isp->is_shdr->sh_type != rep_isp->is_shdr->sh_type) ||
1495 	    ((isp->is_shdr->sh_flags & SHF_GROUP) !=
1496 	    (rep_isp->is_shdr->sh_flags & SHF_GROUP))) {
1497 		*reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SECTION;
1498 		return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1499 	}
1500 
1501 	/*
1502 	 * We found the kept COMDAT section. Now, look at all of the
1503 	 * symbols from the input file that contains it to find the
1504 	 * symbol that corresponds to the one we started with:
1505 	 *	- Hasn't been discarded
1506 	 *	- Has section index of kept section
1507 	 *	- If one symbol has a name, the other must have
1508 	 *		the same name. The st_name field of a symbol
1509 	 *		is 0 if there is no name, and is a string
1510 	 *		table offset otherwise. The string table
1511 	 *		offsets may well not agree --- it is the
1512 	 *		actual string that matters.
1513 	 *	- Type and binding attributes match (st_info)
1514 	 *	- Values match (st_value)
1515 	 *	- Sizes match (st_size)
1516 	 *	- Visibility matches (st_other)
1517 	 */
1518 	scnndx = rep_isp->is_scnndx;
1519 	oldndx = rep_isp->is_file->ifl_oldndx;
1520 	symscnt = rep_isp->is_file->ifl_symscnt;
1521 	while (symscnt--) {
1522 		rep_sdp = *oldndx++;
1523 		if ((rep_sdp == NULL) || (rep_sdp->sd_flags & FLG_SY_ISDISC) ||
1524 		    ((rep_sym = rep_sdp->sd_sym)->st_shndx != scnndx) ||
1525 		    ((sym->st_name == 0) != (rep_sym->st_name == 0)) ||
1526 		    ((sym->st_name != 0) &&
1527 		    (strcmp(sdp->sd_name, rep_sdp->sd_name) != 0)) ||
1528 		    (sym->st_info != rep_sym->st_info) ||
1529 		    (sym->st_value != rep_sym->st_value) ||
1530 		    (sym->st_size != rep_sym->st_size) ||
1531 		    (sym->st_other != rep_sym->st_other))
1532 			continue;
1533 
1534 
1535 		if (ofl->ofl_flags & FLG_OF_VERBOSE) {
1536 			if (sym->st_name != 0) {
1537 				eprintf(ofl->ofl_lml, ERR_WARNING,
1538 				    MSG_INTL(MSG_REL_SLOPCDATNAM),
1539 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
1540 				    reld->rel_rtype, 0, &inv_buf),
1541 				    ifl->ifl_name, reld->rel_isdesc->is_name,
1542 				    rep_sdp->sd_name, isp->is_name,
1543 				    rep_sdp->sd_file->ifl_name);
1544 			} else {
1545 				eprintf(ofl->ofl_lml, ERR_WARNING,
1546 				    MSG_INTL(MSG_REL_SLOPCDATNONAM),
1547 				    conv_reloc_type(ifl->ifl_ehdr->e_machine,
1548 				    reld->rel_rtype, 0, &inv_buf),
1549 				    ifl->ifl_name, reld->rel_isdesc->is_name,
1550 				    isp->is_name, rep_sdp->sd_file->ifl_name);
1551 			}
1552 		}
1553 		DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml, rep_sdp));
1554 		*reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_NONE;
1555 		return (ofl->ofl_sr_cache.sr_rsdp = rep_sdp);
1556 	}
1557 
1558 	/* If didn't return above, we didn't find it */
1559 	*reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SYMBOL;
1560 	return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1561 }
1562 
1563 /*
1564  * Generate a name for a relocation descriptor that has an STT_SECTION
1565  * symbol associated with it. If it is a regular input section, it will
1566  * look like:
1567  *
1568  *	"XXX (section)"
1569  *
1570  * If it is a generated section created to receive the strings from
1571  * input SHF_MERGE|SHF_STRINGS sections, then it will look like:
1572  *
1573  *	"XXX (merged string section)"
1574  *
1575  * STT_SECTION relocations to the same section tend to come in clusters,
1576  * so we use a static variable to retain the last string we generate. If
1577  * another one comes along for the same section before some other section
1578  * intervenes, we will reuse the string.
1579  *
1580  * entry:
1581  *	sdp - STT_SECTION symbol for which a relocation descriptor name
1582  *		should be generated.
1583  *	sd_isc - NULL, or input section that should be used instead of
1584  *		the input section already assocated with the symbol
1585  *		(sdp->sd_isc). This value is set to a non-NULL value when
1586  *		a transition from the old input section to a new one is
1587  *		being made, but the symbol has not yet been updated.
1588  */
1589 const const char *
1590 ld_section_reld_name(Sym_desc *sdp, Is_desc *sd_isc)
1591 {
1592 	static Is_desc	*last_sd_isc = NULL;
1593 	static char	*namestr;
1594 
1595 	const char	*fmt;
1596 	size_t		len;
1597 
1598 	/*
1599 	 * If caller didn't supply a replacement input section,
1600 	 * use the one referenced by the symbol.
1601 	 */
1602 	if (sd_isc == NULL)
1603 		sd_isc = sdp->sd_isc;
1604 
1605 	if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
1606 	    (sd_isc != NULL) && (sd_isc->is_name != NULL)) {
1607 		if (last_sd_isc != sd_isc) {
1608 			fmt = (sd_isc->is_flags & FLG_IS_GNSTRMRG) ?
1609 			    MSG_INTL(MSG_STR_SECTION_MSTR) :
1610 			    MSG_INTL(MSG_STR_SECTION);
1611 			len = strlen(fmt) +
1612 			    strlen(sd_isc->is_name) + 1;
1613 
1614 			if ((namestr = libld_malloc(len)) == 0)
1615 				return (NULL);
1616 			(void) snprintf(namestr, len, fmt,
1617 			    sd_isc->is_name);
1618 			last_sd_isc = sd_isc;	/* Remember for next time */
1619 		}
1620 		return (namestr);
1621 	}
1622 
1623 	return (NULL);
1624 }
1625 
1626 /*
1627  * Generate relocation descriptor and dispatch
1628  */
1629 static uintptr_t
1630 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
1631     Rel *reloc)
1632 {
1633 	Ifl_desc	*ifl = isp->is_file;
1634 	Word		rtype = reld->rel_rtype;
1635 	Sym_desc	*sdp;
1636 	Conv_inv_buf_t	inv_buf;
1637 
1638 	/*
1639 	 * Make sure the relocation is in the valid range.
1640 	 */
1641 	if (rtype >= ld_targ.t_m.m_r_num) {
1642 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT),
1643 		    ifl->ifl_name, isp->is_name, rtype);
1644 		return (S_ERROR);
1645 	}
1646 
1647 	ofl->ofl_entrelscnt++;
1648 
1649 	/*
1650 	 * Special case: a register symbol associated with symbol index 0 is
1651 	 * initialized (i.e., relocated) to a constant from the r_addend field
1652 	 * rather than from a symbol value.
1653 	 */
1654 	if (IS_REGISTER(rtype) && (rsndx == 0)) {
1655 		reld->rel_sym = 0;
1656 		reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY);
1657 
1658 		DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1659 		    ld_targ.t_m.m_mach, isp->is_shdr->sh_type,
1660 		    (void *)reloc, isp->is_name, isp->is_scnndx,
1661 		    reld->rel_sname));
1662 		if (ld_targ.t_mr.mr_reloc_register == NULL) {
1663 			eprintf(ofl->ofl_lml, ERR_FATAL,
1664 			    MSG_INTL(MSG_REL_NOREG));
1665 			return (S_ERROR);
1666 		}
1667 		return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1668 	}
1669 
1670 	/*
1671 	 * Come up with a descriptive name for the symbol:
1672 	 *	- If it is a named symbol, use the name as is
1673 	 *	- If it is an STT_SECTION symbol, generate a descriptive
1674 	 *		string that incorporates the section name.
1675 	 *	- Otherwise, supply an "unknown" string.
1676 	 * Note that bogus relocations can result in a null symbol descriptor
1677 	 * (sdp), the error condition should be caught below after determining
1678 	 * whether a valid symbol name exists.
1679 	 */
1680 	sdp = ifl->ifl_oldndx[rsndx];
1681 	if ((sdp != NULL) && sdp->sd_name && *sdp->sd_name) {
1682 		reld->rel_sname = sdp->sd_name;
1683 	} else if ((sdp != NULL) &&
1684 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
1685 	    (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL)) {
1686 		if ((reld->rel_sname = ld_section_reld_name(sdp, NULL)) == NULL)
1687 			return (S_ERROR);
1688 	} else {
1689 		static char *strunknown;
1690 
1691 		if (strunknown == 0)
1692 			strunknown = (char *)MSG_INTL(MSG_STR_UNKNOWN);
1693 		reld->rel_sname = strunknown;
1694 	}
1695 
1696 	/*
1697 	 * If for some reason we have a null relocation record issue a
1698 	 * warning and continue (the compiler folks can get into this
1699 	 * state some time).  Normal users should never see this error.
1700 	 */
1701 	if (rtype == ld_targ.t_m.m_r_none) {
1702 		DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1703 		    ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type,
1704 		    (void *)reloc, isp->is_name, isp->is_scnndx,
1705 		    reld->rel_sname));
1706 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
1707 		    ifl->ifl_name, isp->is_name);
1708 		return (1);
1709 	}
1710 
1711 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
1712 	    IS_NOTSUP(rtype)) {
1713 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
1714 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1715 		    0, &inv_buf), ifl->ifl_name, isp->is_name);
1716 		return (S_ERROR);
1717 	}
1718 
1719 	/*
1720 	 * If we are here, we know that the relocation requires reference
1721 	 * symbol. If no symbol is assigned, this is a fatal error.
1722 	 */
1723 	if (sdp == NULL) {
1724 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
1725 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1726 		    0, &inv_buf), isp->is_name, ifl->ifl_name,
1727 		    EC_XWORD(reloc->r_offset));
1728 		return (S_ERROR);
1729 	}
1730 
1731 	if (sdp->sd_flags1 & FLG_SY1_IGNORE)
1732 		return (1);
1733 
1734 	/*
1735 	 * If this symbol is part of a DISCARDED section attempt to find another
1736 	 * definition.
1737 	 */
1738 	if (sdp->sd_flags & FLG_SY_ISDISC) {
1739 		Sym_desc	*nsdp = NULL;
1740 		Rlxrel_rej	reject;
1741 
1742 		if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1743 			/*
1744 			 * If "-z relaxreloc", and the input section is COMDAT
1745 			 * that has been assigned to an output section, then
1746 			 * determine if this is a reference to a discarded
1747 			 * COMDAT section that can be replaced with a COMDAT
1748 			 * that has been kept.
1749 			 */
1750 			if ((ofl->ofl_flags1 & FLG_OF1_RLXREL) &&
1751 			    sdp->sd_isc->is_osdesc &&
1752 			    (sdp->sd_isc->is_flags & FLG_IS_COMDAT) &&
1753 			    ((nsdp = sloppy_comdat_reloc(ofl, reld,
1754 			    sdp, &reject)) == NULL)) {
1755 				Shdr	*is_shdr = reld->rel_isdesc->is_shdr;
1756 
1757 				/*
1758 				 * A matching symbol was not found. We will
1759 				 * ignore this relocation. First, we must
1760 				 * decide whether or not to issue a warning.
1761 				 * Warnings are always issued under -z verbose,
1762 				 * but otherwise, we will follow the lead of
1763 				 * the GNU ld and suppress them for certain
1764 				 * cases:
1765 				 *	- It is a non-allocable debug section.
1766 				 *	  The GNU ld tests for these by name,
1767 				 *	  but we are willing to extend it to
1768 				 *	  any non-allocable section.
1769 				 *	- The target section is excluded from
1770 				 *	  sloppy relocations by policy.
1771 				 */
1772 				if (((ofl->ofl_flags & FLG_OF_VERBOSE) != 0) ||
1773 				    ((is_shdr->sh_flags & SHF_ALLOC) &&
1774 				    (reject != RLXREL_REJ_TARGET)))
1775 					eprintf(ofl->ofl_lml, ERR_WARNING,
1776 					    MSG_INTL(MSG_REL_SLOPCDATNOSYM),
1777 					    conv_reloc_type(
1778 					    ifl->ifl_ehdr->e_machine,
1779 					    reld->rel_rtype, 0, &inv_buf),
1780 					    ifl->ifl_name, isp->is_name,
1781 					    demangle(reld->rel_sname),
1782 					    sdp->sd_isc->is_name);
1783 				return (1);
1784 			}
1785 		} else if (reld->rel_sname == sdp->sd_name)
1786 			nsdp = ld_sym_find(sdp->sd_name, SYM_NOHASH, 0, ofl);
1787 
1788 		if (nsdp == NULL) {
1789 			eprintf(ofl->ofl_lml, ERR_FATAL,
1790 			    MSG_INTL(MSG_REL_SYMDISC),
1791 			    conv_reloc_type(ifl->ifl_ehdr->e_machine,
1792 			    reld->rel_rtype, 0, &inv_buf), ifl->ifl_name,
1793 			    isp->is_name, demangle(reld->rel_sname),
1794 			    sdp->sd_isc->is_name);
1795 			return (S_ERROR);
1796 		}
1797 		ifl->ifl_oldndx[rsndx] = sdp = nsdp;
1798 	}
1799 
1800 	/*
1801 	 * If this is a global symbol, determine whether its visibility needs
1802 	 * adjusting.
1803 	 */
1804 	if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0))
1805 		ld_sym_adjust_vis(sdp, ofl);
1806 
1807 	/*
1808 	 * Ignore any relocation against a section that will not be in the
1809 	 * output file (has been stripped).
1810 	 */
1811 	if ((sdp->sd_isc == 0) &&
1812 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))
1813 		return (1);
1814 
1815 	/*
1816 	 * If the input section exists, but the section has not been associated
1817 	 * to an output section, then this is a little suspicious.
1818 	 */
1819 	if (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0) &&
1820 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
1821 		eprintf(ofl->ofl_lml, ERR_WARNING, MSG_INTL(MSG_RELINVSEC),
1822 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1823 		    0, &inv_buf), ifl->ifl_name, isp->is_name,
1824 		    sdp->sd_isc->is_name);
1825 		return (1);
1826 	}
1827 
1828 	/*
1829 	 * If the symbol for this relocation is invalid (which should have
1830 	 * generated a message during symbol processing), or the relocation
1831 	 * record's symbol reference is in any other way invalid, then it's
1832 	 * about time we gave up.
1833 	 */
1834 	if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
1835 	    (rsndx >= ifl->ifl_symscnt)) {
1836 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
1837 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1838 		    0, &inv_buf), ifl->ifl_name, isp->is_name,
1839 		    demangle(reld->rel_sname), EC_XWORD(reloc->r_offset),
1840 		    EC_WORD(rsndx));
1841 		return (S_ERROR);
1842 	}
1843 
1844 	/*
1845 	 * Size relocations against section symbols are presently unsupported.
1846 	 * There is a question as to whether the input section size, or output
1847 	 * section size would be used.  Until an explicit requirement is
1848 	 * established for either case, we'll punt.
1849 	 */
1850 	if (IS_SIZE(rtype) &&
1851 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
1852 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE),
1853 		    conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1854 		    0, &inv_buf), ifl->ifl_name, isp->is_name);
1855 		return (S_ERROR);
1856 	}
1857 
1858 	reld->rel_sym = sdp;
1859 	return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name,
1860 	    isp->is_scnndx));
1861 }
1862 
1863 static uintptr_t
1864 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect)
1865 {
1866 	Rel		*rend;		/* end of relocation section data */
1867 	Rel		*reloc;		/* current relocation entry */
1868 	Xword		rsize;		/* size of relocation section data */
1869 	Xword		entsize;	/* size of relocation entry */
1870 	Rel_desc	reld;		/* relocation descriptor */
1871 	Shdr *		shdr;
1872 	Word		flags = 0;
1873 	uintptr_t	ret = 1;
1874 
1875 	shdr = rsect->is_shdr;
1876 	rsize = shdr->sh_size;
1877 	reloc = (Rel *)rsect->is_indata->d_buf;
1878 
1879 	/*
1880 	 * Decide entry size.
1881 	 */
1882 	if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) {
1883 		if (shdr->sh_type == SHT_RELA)
1884 			entsize = sizeof (Rela);
1885 		else
1886 			entsize = sizeof (Rel);
1887 	}
1888 
1889 	/*
1890 	 * Build up the basic information in for the Rel_desc structure.
1891 	 */
1892 	reld.rel_osdesc = osect;
1893 	reld.rel_isdesc = isect;
1894 	reld.rel_move = 0;
1895 
1896 	if ((ofl->ofl_flags & FLG_OF_RELOBJ) ||
1897 	    (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD)))
1898 		flags |= FLG_REL_LOAD;
1899 
1900 	if (shdr->sh_info == 0)
1901 		flags |= FLG_REL_NOINFO;
1902 
1903 	DBG_CALL(Dbg_reloc_proc(ofl->ofl_lml, osect, isect, rsect));
1904 
1905 	for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
1906 	    reloc < rend;
1907 	    reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
1908 		Word	rsndx;
1909 
1910 		/*
1911 		 * Initialize the relocation record information and process
1912 		 * the individual relocation.  Reinitialize the flags to
1913 		 * insure we don't carry any state over from the previous
1914 		 * relocation records processing.
1915 		 */
1916 		reld.rel_flags = flags;
1917 		rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld, (void *)reloc);
1918 
1919 		if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR)
1920 			ret = S_ERROR;
1921 	}
1922 	return (ret);
1923 }
1924 
1925 static uintptr_t
1926 reloc_segments(int wr_flag, Ofl_desc *ofl)
1927 {
1928 	Aliste		idx1;
1929 	Sg_desc		*sgp;
1930 	Is_desc		*isp;
1931 
1932 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
1933 		Os_desc	*osp;
1934 		Aliste	idx2;
1935 
1936 		if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag)
1937 			continue;
1938 
1939 		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
1940 			Is_desc	*risp;
1941 			Aliste	idx3;
1942 
1943 			osp->os_szoutrels = 0;
1944 			for (APLIST_TRAVERSE(osp->os_relisdescs, idx3, risp)) {
1945 				Word	indx;
1946 
1947 				/*
1948 				 * Determine the input section that this
1949 				 * relocation information refers to.
1950 				 */
1951 				indx = risp->is_shdr->sh_info;
1952 				isp = risp->is_file->ifl_isdesc[indx];
1953 
1954 				/*
1955 				 * Do not process relocations against sections
1956 				 * which are being discarded (COMDAT)
1957 				 */
1958 				if (isp->is_flags & FLG_IS_DISCARD)
1959 					continue;
1960 
1961 				if (reloc_section(ofl, isp, risp, osp) ==
1962 				    S_ERROR)
1963 					return (S_ERROR);
1964 			}
1965 
1966 			/*
1967 			 * Check for relocations against non-writable
1968 			 * allocatable sections.
1969 			 */
1970 			if (osp->os_szoutrels &&
1971 			    (sgp->sg_phdr.p_type == PT_LOAD) &&
1972 			    ((sgp->sg_phdr.p_flags & PF_W) == 0)) {
1973 				ofl->ofl_flags |= FLG_OF_TEXTREL;
1974 				ofl->ofl_dtflags |= DF_TEXTREL;
1975 			}
1976 		}
1977 	}
1978 
1979 	return (1);
1980 }
1981 
1982 /*
1983  * Move Section related function
1984  * Get move entry
1985  */
1986 static Move *
1987 get_move_entry(Is_desc *rsect, Xword roffset)
1988 {
1989 	Ifl_desc	*ifile = rsect->is_file;
1990 	Shdr		*rshdr = rsect->is_shdr;
1991 	Is_desc		*misp;
1992 	Shdr		*mshdr;
1993 	Xword 		midx;
1994 	Move		*mvp;
1995 
1996 	/*
1997 	 * Set info for the target move section
1998 	 */
1999 	misp = ifile->ifl_isdesc[rshdr->sh_info];
2000 	mshdr = misp->is_shdr;
2001 
2002 	if (mshdr->sh_entsize == 0)
2003 		return (NULL);
2004 
2005 	/*
2006 	 * If this is an invalid entry, return NULL.
2007 	 */
2008 	midx = roffset / mshdr->sh_entsize;
2009 	if ((midx * mshdr->sh_entsize) >= mshdr->sh_size)
2010 		return (NULL);
2011 
2012 	mvp = (Move *)misp->is_indata->d_buf;
2013 	mvp += midx;
2014 	return (mvp);
2015 }
2016 
2017 /*
2018  * Relocation against Move Table.
2019  */
2020 static uintptr_t
2021 process_movereloc(Ofl_desc *ofl, Is_desc *rsect)
2022 {
2023 	Ifl_desc	*file = rsect->is_file;
2024 	Rel		*rend, *reloc;
2025 	Xword 		rsize, entsize;
2026 	Rel_desc 	reld;
2027 
2028 	rsize = rsect->is_shdr->sh_size;
2029 	reloc = (Rel *)rsect->is_indata->d_buf;
2030 
2031 	/*
2032 	 * Decide entry size.
2033 	 */
2034 	entsize = rsect->is_shdr->sh_entsize;
2035 	if ((entsize == 0) ||
2036 	    (entsize > rsect->is_shdr->sh_size)) {
2037 		if (rsect->is_shdr->sh_type == SHT_RELA)
2038 			entsize = sizeof (Rela);
2039 		else
2040 			entsize = sizeof (Rel);
2041 	}
2042 
2043 	/*
2044 	 * Go through the relocation entries.
2045 	 */
2046 	for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
2047 	    reloc < rend;
2048 	    reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
2049 		Sym_desc	*psdp;
2050 		Move		*mvp;
2051 		Word		rsndx;
2052 
2053 		/*
2054 		 * Initialize the relocation record information.
2055 		 */
2056 		reld.rel_flags = FLG_REL_LOAD;
2057 		rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld, (void *)reloc);
2058 
2059 		if (((mvp = get_move_entry(rsect, reloc->r_offset)) == NULL) ||
2060 		    ((reld.rel_move = libld_malloc(sizeof (Mv_reloc))) == NULL))
2061 			return (S_ERROR);
2062 
2063 		psdp = file->ifl_oldndx[ELF_M_SYM(mvp->m_info)];
2064 		reld.rel_move->mr_move = mvp;
2065 		reld.rel_move->mr_sym = psdp;
2066 
2067 		if (psdp->sd_flags & FLG_SY_PAREXPN) {
2068 			int	_num, num = mvp->m_repeat;
2069 
2070 			reld.rel_osdesc = ofl->ofl_isparexpn->is_osdesc;
2071 			reld.rel_isdesc = ofl->ofl_isparexpn;
2072 			reld.rel_roffset = mvp->m_poffset;
2073 
2074 			for (_num = 0; _num < num; _num++) {
2075 				reld.rel_roffset +=
2076 				    /* LINTED */
2077 				    (_num * ELF_M_SIZE(mvp->m_info));
2078 
2079 				/*
2080 				 * Generate Reld
2081 				 */
2082 				if (process_reld(ofl,
2083 				    rsect, &reld, rsndx, reloc) == S_ERROR)
2084 					return (S_ERROR);
2085 			}
2086 		} else {
2087 			/*
2088 			 * Generate Reld
2089 			 */
2090 			reld.rel_flags |= FLG_REL_MOVETAB;
2091 			reld.rel_osdesc = ofl->ofl_osmove;
2092 			reld.rel_isdesc =
2093 			    ofl->ofl_osmove->os_isdescs->apl_data[0];
2094 
2095 			if (process_reld(ofl,
2096 			    rsect, &reld, rsndx, reloc) == S_ERROR)
2097 				return (S_ERROR);
2098 		}
2099 	}
2100 	return (1);
2101 }
2102 
2103 /*
2104  * This function is similar to reloc_init().
2105  *
2106  * This function is called when the SHT_SUNW_move table is expanded and there
2107  * are relocations against the SHT_SUNW_move section.
2108  */
2109 static uintptr_t
2110 reloc_movesections(Ofl_desc *ofl)
2111 {
2112 	Aliste		idx;
2113 	Is_desc		*risp;
2114 	uintptr_t	ret = 1;
2115 
2116 	/*
2117 	 * Generate/Expand relocation entries
2118 	 */
2119 	for (APLIST_TRAVERSE(ofl->ofl_ismoverel, idx, risp)) {
2120 		if (process_movereloc(ofl, risp) == S_ERROR)
2121 			ret = S_ERROR;
2122 	}
2123 
2124 	return (ret);
2125 }
2126 
2127 /*
2128  * Count the number of output relocation entries, global offset table entries,
2129  * and procedure linkage table entries.  This function searches the segment and
2130  * outsect lists and passes each input reloc section to process_reloc().
2131  * It allocates space for any output relocations needed.  And builds up
2132  * the relocation structures for later processing.
2133  */
2134 uintptr_t
2135 ld_reloc_init(Ofl_desc *ofl)
2136 {
2137 	Aliste		idx;
2138 	Is_desc		*isp;
2139 	Sym_desc	*sdp;
2140 
2141 	/*
2142 	 * At this point we have finished processing all input symbols.  Make
2143 	 * sure we add any absolute (internal) symbols before continuing with
2144 	 * any relocation processing.
2145 	 */
2146 	if (ld_sym_spec(ofl) == S_ERROR)
2147 		return (S_ERROR);
2148 
2149 	ofl->ofl_gotcnt = ld_targ.t_m.m_got_xnumber;
2150 
2151 	/*
2152 	 * First process all of the relocations against NON-writable
2153 	 * segments followed by relocations against the writeable segments.
2154 	 *
2155 	 * This separation is so that when the writable segments are processed
2156 	 * we know whether or not a COPYRELOC will be produced for any symbols.
2157 	 * If relocations aren't processed in this order, a COPYRELOC and a
2158 	 * regular relocation can be produced against the same symbol.  The
2159 	 * regular relocation would be redundant.
2160 	 */
2161 	if (reloc_segments(0, ofl) == S_ERROR)
2162 		return (S_ERROR);
2163 
2164 	if (reloc_segments(PF_W, ofl) == S_ERROR)
2165 		return (S_ERROR);
2166 
2167 	/*
2168 	 * Process any extra relocations.  These are relocation sections that
2169 	 * have a NULL sh_info.
2170 	 */
2171 	for (APLIST_TRAVERSE(ofl->ofl_extrarels, idx, isp)) {
2172 		if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR)
2173 			return (S_ERROR);
2174 	}
2175 
2176 	/*
2177 	 * If there were relocation against move table,
2178 	 * process the relocation sections.
2179 	 */
2180 	if (reloc_movesections(ofl) == S_ERROR)
2181 		return (S_ERROR);
2182 
2183 	/*
2184 	 * Now all the relocations are pre-processed,
2185 	 * check the validity of copy relocations.
2186 	 */
2187 	if (ofl->ofl_copyrels) {
2188 		Copy_rel	*crp;
2189 
2190 		for (ALIST_TRAVERSE(ofl->ofl_copyrels, idx, crp)) {
2191 			/*
2192 			 * If there were no displacement relocation
2193 			 * in this file, don't worry about it.
2194 			 */
2195 			if (crp->c_sdp->sd_file->ifl_flags &
2196 			    (FLG_IF_DISPPEND | FLG_IF_DISPDONE))
2197 				is_disp_copied(ofl, crp);
2198 		}
2199 	}
2200 
2201 	/*
2202 	 * GOT sections are created for dynamic executables and shared objects
2203 	 * if the FLG_OF_BLDGOT is set, or explicit reference has been made to
2204 	 * a GOT symbol.
2205 	 */
2206 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
2207 	    ((ofl->ofl_flags & FLG_OF_BLDGOT) ||
2208 	    ((((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL),
2209 	    SYM_NOHASH, 0, ofl)) != 0) ||
2210 	    ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
2211 	    SYM_NOHASH, 0, ofl)) != 0)) && (sdp->sd_ref != REF_DYN_SEEN)))) {
2212 		if (ld_make_got(ofl) == S_ERROR)
2213 			return (S_ERROR);
2214 
2215 		/* Allocate the GOT if required by target */
2216 		if ((ld_targ.t_mr.mr_allocate_got != NULL) &&
2217 		    ((*ld_targ.t_mr.mr_allocate_got)(ofl) == S_ERROR))
2218 			return (S_ERROR);
2219 	}
2220 
2221 	return (1);
2222 }
2223 
2224 /*
2225  * Simple comparison routine to be used by qsort() for
2226  * the sorting of the output relocation list.
2227  *
2228  * The reloc_compare() routine results in a relocation
2229  * table which is located on:
2230  *
2231  *	file referenced (NEEDED NDX)
2232  *	referenced symbol
2233  *	relocation offset
2234  *
2235  * This provides the most efficient traversal of the relocation
2236  * table at run-time.
2237  */
2238 static int
2239 reloc_compare(Reloc_list *i, Reloc_list *j)
2240 {
2241 
2242 	/*
2243 	 * first - sort on neededndx
2244 	 */
2245 	if (i->rl_key1 > j->rl_key1)
2246 		return (1);
2247 	if (i->rl_key1 < j->rl_key1)
2248 		return (-1);
2249 
2250 	/*
2251 	 * Then sort on symbol
2252 	 */
2253 	if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2)
2254 		return (1);
2255 	if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2)
2256 		return (-1);
2257 
2258 	/*
2259 	 * i->key2 == j->key2
2260 	 *
2261 	 * At this point we fall back to key2 (offsets) to
2262 	 * sort the output relocations.  Ideally this will
2263 	 * make for the most efficient processing of these
2264 	 * relocations at run-time.
2265 	 */
2266 	if (i->rl_key3 > j->rl_key3)
2267 		return (1);
2268 	if (i->rl_key3 < j->rl_key3)
2269 		return (-1);
2270 	return (0);
2271 }
2272 
2273 static uintptr_t
2274 do_sorted_outrelocs(Ofl_desc *ofl)
2275 {
2276 	Rel_desc	*orsp;
2277 	Rel_cache	*rcp;
2278 	Aliste		idx;
2279 	Reloc_list	*sorted_list;
2280 	Word		index = 0;
2281 	int		debug = 0;
2282 	uintptr_t	error = 1;
2283 
2284 	if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) *
2285 	    ofl->ofl_reloccnt))) == NULL)
2286 		return (S_ERROR);
2287 
2288 	/*
2289 	 * All but the PLT output relocations are sorted in the output file
2290 	 * based upon their sym_desc.  By doing this multiple relocations
2291 	 * against the same symbol are grouped together, thus when the object
2292 	 * is later relocated by ld.so.1 it will take advantage of the symbol
2293 	 * cache that ld.so.1 has.  This can significantly reduce the runtime
2294 	 * relocation cost of a dynamic object.
2295 	 *
2296 	 * PLT relocations are not sorted because the order of the PLT
2297 	 * relocations is used by ld.so.1 to determine what symbol a PLT
2298 	 * relocation is against.
2299 	 */
2300 	for (APLIST_TRAVERSE(ofl->ofl_outrels, idx, rcp)) {
2301 		/*LINTED*/
2302 		for (orsp = (Rel_desc *)(rcp + 1);
2303 		    orsp < rcp->rc_free; orsp++) {
2304 			if (debug == 0) {
2305 				DBG_CALL(Dbg_reloc_dooutrel(ofl->ofl_lml,
2306 				    ld_targ.t_m.m_rel_sht_type));
2307 				debug = 1;
2308 			}
2309 
2310 			/*
2311 			 * If it's a PLT relocation we output it now in the
2312 			 * order that it was originally processed.
2313 			 */
2314 			if (orsp->rel_flags & FLG_REL_PLT) {
2315 				if ((*ld_targ.t_mr.mr_perform_outreloc)(orsp,
2316 				    ofl) == S_ERROR)
2317 					error = S_ERROR;
2318 				continue;
2319 			}
2320 
2321 			if ((orsp->rel_rtype == ld_targ.t_m.m_r_relative) ||
2322 			    (orsp->rel_rtype == ld_targ.t_m.m_r_register)) {
2323 				sorted_list[index].rl_key1 = 0;
2324 				sorted_list[index].rl_key2 =
2325 				    /* LINTED */
2326 				    (Sym_desc *)(uintptr_t)orsp->rel_rtype;
2327 			} else {
2328 				sorted_list[index].rl_key1 =
2329 				    orsp->rel_sym->sd_file->ifl_neededndx;
2330 				sorted_list[index].rl_key2 =
2331 				    orsp->rel_sym;
2332 			}
2333 
2334 			if (orsp->rel_flags & FLG_REL_GOT)
2335 				sorted_list[index].rl_key3 =
2336 				    (*ld_targ.t_mr.mr_calc_got_offset)(orsp,
2337 				    ofl);
2338 			else {
2339 				if (orsp->rel_rtype == ld_targ.t_m.m_r_register)
2340 					sorted_list[index].rl_key3 = 0;
2341 				else {
2342 					sorted_list[index].rl_key3 =
2343 					    orsp->rel_roffset +
2344 					    (Xword)_elf_getxoff(orsp->
2345 					    rel_isdesc->is_indata) +
2346 					    orsp->rel_isdesc->is_osdesc->
2347 					    os_shdr->sh_addr;
2348 				}
2349 			}
2350 
2351 			sorted_list[index++].rl_rsp = orsp;
2352 		}
2353 	}
2354 
2355 	qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list),
2356 	    (int (*)(const void *, const void *))reloc_compare);
2357 
2358 	/*
2359 	 * All output relocations have now been sorted, go through
2360 	 * and process each relocation.
2361 	 */
2362 	for (index = 0; index < ofl->ofl_reloccnt; index++) {
2363 		if ((*ld_targ.t_mr.mr_perform_outreloc)
2364 		    (sorted_list[index].rl_rsp, ofl) == S_ERROR)
2365 			error = S_ERROR;
2366 	}
2367 
2368 	return (error);
2369 }
2370 
2371 /*
2372  * Process relocations.  Finds every input relocation section for each output
2373  * section and invokes reloc_section() to relocate that section.
2374  */
2375 uintptr_t
2376 ld_reloc_process(Ofl_desc *ofl)
2377 {
2378 	Sg_desc		*sgp;
2379 	Os_desc		*osp;
2380 	Word		ndx = 0;
2381 	ofl_flag_t	flags = ofl->ofl_flags;
2382 	Shdr		*shdr;
2383 
2384 	/*
2385 	 * Determine the index of the symbol table that will be referenced by
2386 	 * the relocation entries.
2387 	 */
2388 	if ((flags & (FLG_OF_DYNAMIC|FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC)
2389 		/* LINTED */
2390 		ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
2391 	else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
2392 		/* LINTED */
2393 		ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
2394 
2395 	/*
2396 	 * Re-initialize counters. These are used to provide relocation
2397 	 * offsets within the output buffers.
2398 	 */
2399 	ofl->ofl_relocpltsz = 0;
2400 	ofl->ofl_relocgotsz = 0;
2401 	ofl->ofl_relocbsssz = 0;
2402 
2403 	/*
2404 	 * Now that the output file is created and symbol update has occurred,
2405 	 * process the relocations collected in process_reloc().
2406 	 */
2407 	if (do_sorted_outrelocs(ofl) == S_ERROR)
2408 		return (S_ERROR);
2409 
2410 	if ((*ld_targ.t_mr.mr_do_activerelocs)(ofl) == S_ERROR)
2411 		return (S_ERROR);
2412 
2413 	if ((flags & FLG_OF_COMREL) == 0) {
2414 		Aliste	idx1;
2415 
2416 		/*
2417 		 * Process the relocation sections:
2418 		 *
2419 		 *  o	for each relocation section generated for the output
2420 		 *	image update its shdr information to reflect the
2421 		 *	symbol table it needs (sh_link) and the section to
2422 		 *	which the relocation must be applied (sh_info).
2423 		 */
2424 		for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
2425 			Os_desc *osp;
2426 			Aliste	idx2;
2427 
2428 			for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
2429 				if (osp->os_relosdesc == 0)
2430 					continue;
2431 
2432 				shdr = osp->os_relosdesc->os_shdr;
2433 				shdr->sh_link = ndx;
2434 				/* LINTED */
2435 				shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2436 			}
2437 		}
2438 
2439 		/*
2440 		 * Since the .rel[a] section is not tied to any specific
2441 		 * section, we'd not have found it above.
2442 		 */
2443 		if ((osp = ofl->ofl_osrel) != NULL) {
2444 			shdr = osp->os_shdr;
2445 			shdr->sh_link = ndx;
2446 			shdr->sh_info = 0;
2447 		}
2448 	} else {
2449 		/*
2450 		 * We only have two relocation sections here, (PLT's,
2451 		 * coalesced) so just hit them directly instead of stepping
2452 		 * over the output sections.
2453 		 */
2454 		if ((osp = ofl->ofl_osrelhead) != NULL) {
2455 			shdr = osp->os_shdr;
2456 			shdr->sh_link = ndx;
2457 			shdr->sh_info = 0;
2458 		}
2459 		if (((osp = ofl->ofl_osplt) != NULL) && osp->os_relosdesc) {
2460 			shdr = osp->os_relosdesc->os_shdr;
2461 			shdr->sh_link = ndx;
2462 			/* LINTED */
2463 			shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2464 		}
2465 	}
2466 
2467 	/*
2468 	 * If the -z text option was given, and we have output relocations
2469 	 * against a non-writable, allocatable section, issue a diagnostic and
2470 	 * return (the actual entries that caused this error would have been
2471 	 * output during the relocating section phase).
2472 	 */
2473 	if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) ==
2474 	    (FLG_OF_PURETXT | FLG_OF_TEXTREL)) {
2475 		eprintf(ofl->ofl_lml, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
2476 		return (S_ERROR);
2477 	}
2478 
2479 	/*
2480 	 * Finally, initialize the first got entry with the address of the
2481 	 * .dynamic section (_DYNAMIC).
2482 	 */
2483 	if (flags & FLG_OF_DYNAMIC) {
2484 		if ((*ld_targ.t_mr.mr_fillin_gotplt)(ofl) == S_ERROR)
2485 			return (S_ERROR);
2486 	}
2487 
2488 	/*
2489 	 * Now that any GOT information has been written, display the debugging
2490 	 * information if required.
2491 	 */
2492 	if ((osp = ofl->ofl_osgot) != NULL)
2493 		DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1,
2494 		    ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
2495 
2496 	return (1);
2497 }
2498 
2499 /*
2500  * If the -z text option was given, and we have output relocations against a
2501  * non-writable, allocatable section, issue a diagnostic. Print offending
2502  * symbols in tabular form similar to the way undefined symbols are presented.
2503  * Called from reloc_count().  The actual fatal error condition is triggered on
2504  * in reloc_process() above.
2505  *
2506  * Note.  For historic reasons -ztext is not a default option (however all OS
2507  * shared object builds use this option).  It can be argued that this option
2508  * should also be default when generating an a.out (see 1163979).  However, if
2509  * an a.out contains text relocations it is either because the user is creating
2510  * something pretty weird (they've used the -b or -znodefs options), or because
2511  * the library against which they're building wasn't constructed correctly (ie.
2512  * a function has a NOTYPE type, in which case the a.out won't generate an
2513  * associated plt).  In the latter case the builder of the a.out can't do
2514  * anything to fix the error - thus we've chosen not to give the user an error,
2515  * or warning, for this case.
2516  */
2517 static void
2518 reloc_remain_title(Ofl_desc *ofl, int warning)
2519 {
2520 	const char	*str1;
2521 
2522 	if (warning)
2523 		str1 = MSG_INTL(MSG_REL_RMN_ITM_13);
2524 	else
2525 		str1 = MSG_INTL(MSG_REL_RMN_ITM_11);
2526 
2527 	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), str1,
2528 	    MSG_INTL(MSG_REL_RMN_ITM_31), MSG_INTL(MSG_REL_RMN_ITM_12),
2529 	    MSG_INTL(MSG_REL_RMN_ITM_2), MSG_INTL(MSG_REL_RMN_ITM_32));
2530 }
2531 
2532 void
2533 ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl)
2534 {
2535 	static Boolean	reloc_title = TRUE;
2536 
2537 	/*
2538 	 * -ztextoff
2539 	 */
2540 	if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)
2541 		return;
2542 
2543 	/*
2544 	 * Only give relocation errors against loadable read-only segments.
2545 	 */
2546 	if ((orsp->rel_rtype == ld_targ.t_m.m_r_register) || (!osp) ||
2547 	    (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) ||
2548 	    (osp->os_sgdesc->sg_phdr.p_flags & PF_W))
2549 		return;
2550 
2551 	/*
2552 	 * If we are in -ztextwarn mode, it's a silent error if a relocation is
2553 	 * due to a 'WEAK REFERENCE'.  This is because if the symbol is not
2554 	 * provided at run-time we will not perform a text-relocation.
2555 	 */
2556 	if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) &&
2557 	    (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) &&
2558 	    (orsp->rel_sym->sd_sym->st_shndx == SHN_UNDEF))
2559 		return;
2560 
2561 	if (reloc_title) {
2562 		/*
2563 		 * If building with '-ztext' then emit a fatal error.  If
2564 		 * building a executable then only emit a 'warning'.
2565 		 */
2566 		if (ofl->ofl_flags & FLG_OF_PURETXT)
2567 			reloc_remain_title(ofl, 0);
2568 		else
2569 			reloc_remain_title(ofl, 1);
2570 		reloc_title = FALSE;
2571 	}
2572 
2573 	eprintf(ofl->ofl_lml, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2),
2574 	    demangle(orsp->rel_sname), EC_OFF(orsp->rel_roffset),
2575 	    orsp->rel_isdesc->is_file->ifl_name);
2576 }
2577 
2578 /*
2579  * Generic encapsulation for generating a TLS got index.
2580  */
2581 uintptr_t
2582 ld_assign_got_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl, Sym_desc *sdp,
2583     Gotndx *gnp, Gotref gref, Word rflag, Word ortype, Word rtype1, Word rtype2)
2584 {
2585 	Word	rflags;
2586 
2587 	if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
2588 	    gref, ofl, rsp, sdp) == S_ERROR)
2589 		return (S_ERROR);
2590 
2591 	rflags = FLG_REL_GOT | rflag;
2592 	if (local)
2593 		rflags |= FLG_REL_SCNNDX;
2594 	rsp->rel_rtype = rtype1;
2595 
2596 	if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) == S_ERROR)
2597 		return (S_ERROR);
2598 
2599 	if (local && (gref == GOT_REF_TLSIE)) {
2600 		/*
2601 		 * If this is a local LE TLS symbol, then the symbol won't be
2602 		 * available at runtime.  The value of the local symbol will
2603 		 * be placed in the associated got entry, and the got
2604 		 * relocation is reassigned to a section symbol.
2605 		 */
2606 		if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2607 			return (S_ERROR);
2608 	}
2609 
2610 	if (rtype2) {
2611 		rflags = FLG_REL_GOT | rflag;
2612 		rsp->rel_rtype = rtype2;
2613 
2614 		if (local) {
2615 			if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2616 				return (S_ERROR);
2617 		} else {
2618 			if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) ==
2619 			    S_ERROR)
2620 				return (S_ERROR);
2621 		}
2622 	}
2623 
2624 	rsp->rel_rtype = ortype;
2625 
2626 	return (1);
2627 }
2628 
2629 /*
2630  * Move Section related function
2631  */
2632 static void
2633 newroffset_for_move(Sym_desc *sdp, Move *mvp, Xword offset1, Xword *offset2)
2634 {
2635 	Mv_desc		*mdp;
2636 	Aliste		idx;
2637 
2638 	/*
2639 	 * Search for matching move entry.
2640 	 */
2641 	for (ALIST_TRAVERSE(sdp->sd_move, idx, mdp)) {
2642 		if (mdp->md_move == mvp) {
2643 			/*
2644 			 * Update r_offset
2645 			 */
2646 			*offset2 = (Xword)((mdp->md_oidx - 1) * sizeof (Move) +
2647 			    offset1 % sizeof (Move));
2648 			return;
2649 		}
2650 	}
2651 }
2652 
2653 void
2654 ld_adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp)
2655 {
2656 	Move		*move = arsp->rel_move->mr_move;
2657 	Sym_desc	*psdp = arsp->rel_move->mr_sym;
2658 	Xword		newoffset;
2659 
2660 	if (arsp->rel_flags & FLG_REL_MOVETAB) {
2661 		/*
2662 		 * We are relocating the move table itself.
2663 		 */
2664 		newroffset_for_move(psdp, move, arsp->rel_roffset,
2665 		    &newoffset);
2666 		DBG_CALL(Dbg_move_adjmovereloc(ofl->ofl_lml, arsp->rel_roffset,
2667 		    newoffset, psdp->sd_name));
2668 		arsp->rel_roffset = newoffset;
2669 	} else {
2670 		/*
2671 		 * We are expanding the partial symbol.  So we are generating
2672 		 * the relocation entry relocating the expanded partial symbol.
2673 		 */
2674 		arsp->rel_roffset += psdp->sd_sym->st_value -
2675 		    ofl->ofl_isparexpn->is_osdesc->os_shdr->sh_addr;
2676 		DBG_CALL(Dbg_move_adjexpandreloc(ofl->ofl_lml,
2677 		    arsp->rel_roffset, psdp->sd_name));
2678 	}
2679 }
2680 
2681 /*
2682  * Partially Initialized Symbol Handling routines
2683  * For RELA architecture, the second argument is reld->rel_raddend.
2684  * For REL  architecure, the second argument is the value stored
2685  *	at the relocation target address.
2686  */
2687 Sym_desc *
2688 ld_am_I_partial(Rel_desc *reld, Xword val)
2689 {
2690 	Ifl_desc	*ifile = reld->rel_sym->sd_isc->is_file;
2691 	int 		nlocs = ifile->ifl_locscnt, i;
2692 
2693 	for (i = 1; i < nlocs; i++) {
2694 		Sym		*osym;
2695 		Sym_desc	*symd = ifile->ifl_oldndx[i];
2696 
2697 		if ((osym = symd->sd_osym) == 0)
2698 			continue;
2699 		if ((symd->sd_flags & FLG_SY_PAREXPN) == 0)
2700 			continue;
2701 		if ((osym->st_value <= val) &&
2702 		    (osym->st_value + osym->st_size > val))
2703 			return (symd);
2704 	}
2705 	return (NULL);
2706 }
2707 
2708 /*
2709  * Return True (1) if the code processing the given relocation
2710  * needs to perform byte swapping when accessing the section data.
2711  */
2712 int
2713 ld_swap_reloc_data(Ofl_desc *ofl, Rel_desc *rsp)
2714 {
2715 	/*
2716 	 * In a cross-link situation where the linker host and target
2717 	 * have opposite byte orders, it can be necessary to swap bytes
2718 	 * when doing relocation processing. This is indicated by the
2719 	 * presence of the FLG_OF1_ENCDIFF flag bit. However, swapping
2720 	 * is only needed for the section types that libelf doesn't
2721 	 * automatically xlate.
2722 	 */
2723 	if ((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) {
2724 		switch (rsp->rel_osdesc->os_shdr->sh_type) {
2725 		case SHT_PROGBITS:
2726 			return (1);
2727 
2728 		case SHT_SPARC_GOTDATA:
2729 			if (ld_targ.t_m.m_mach ==
2730 			    LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9))
2731 				return (1);
2732 			break;
2733 
2734 		case SHT_AMD64_UNWIND:
2735 			if (ld_targ.t_m.m_mach == EM_AMD64)
2736 				return (1);
2737 			break;
2738 		}
2739 	}
2740 
2741 	/*
2742 	 * If FLG_OF1_ENCDIFF isn't set, or the section isn't
2743 	 * progbits (or similar), then no swapping is needed.
2744 	 */
2745 	return (0);
2746 }
2747 
2748 
2749 
2750 /*
2751  * Obtain the current value at the given relocation target.
2752  *
2753  * entry:
2754  *	ofl - Output file descriptor
2755  *	rsp - Relocation record
2756  *	data - Pointer to relocation target
2757  *	value - Address of variable to recieve value
2758  *
2759  * exit:
2760  *	The value of the data at the relocation target has
2761  *	been stored in value.
2762  */
2763 int
2764 ld_reloc_targval_get(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword *value)
2765 {
2766 	const Rel_entry	*rep;
2767 
2768 	rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
2769 
2770 	switch (rep->re_fsize) {
2771 	case 1:
2772 		/* LINTED */
2773 		*value = (Xword) *((uchar_t *)data);
2774 		break;
2775 	case 2:
2776 		{
2777 			Half	v;
2778 			uchar_t	*v_bytes = (uchar_t *)&v;
2779 
2780 			if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
2781 				UL_ASSIGN_BSWAP_HALF(v_bytes, data);
2782 			} else {
2783 				UL_ASSIGN_HALF(v_bytes, data);
2784 			}
2785 			*value = (Xword) v;
2786 		}
2787 		break;
2788 	case 4:
2789 		{
2790 			Word	v;
2791 			uchar_t	*v_bytes = (uchar_t *)&v;
2792 
2793 			if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
2794 				UL_ASSIGN_BSWAP_WORD(v_bytes, data);
2795 			} else {
2796 				UL_ASSIGN_WORD(v_bytes, data);
2797 			}
2798 			*value = (Xword) v;
2799 		}
2800 		break;
2801 	default:
2802 		{
2803 			Conv_inv_buf_t inv_buf;
2804 			eprintf(ofl->ofl_lml, ERR_FATAL,
2805 			    MSG_INTL(MSG_REL_UNSUPSZ),
2806 			    conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
2807 			    0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
2808 			    (rsp->rel_sname ? demangle(rsp->rel_sname) :
2809 			    MSG_INTL(MSG_STR_UNKNOWN)), (int)rep->re_fsize);
2810 		}
2811 		return (0);
2812 	}
2813 	return (1);
2814 }
2815 
2816 
2817 /*
2818  * Set the value at the given relocation target.
2819  *
2820  * entry:
2821  *	ofl - Output file descriptor
2822  *	rsp - Relocation record
2823  *	data - Pointer to relocation target
2824  *	value - Address of variable to recieve value
2825  *
2826  * exit:
2827  *	The value of the data at the relocation target has
2828  *	been stored in value.
2829  */
2830 int
2831 ld_reloc_targval_set(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword value)
2832 {
2833 	const Rel_entry	*rep;
2834 
2835 	rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
2836 
2837 	switch (rep->re_fsize) {
2838 	case 1:
2839 		/* LINTED */
2840 		*((uchar_t *)data) = (uchar_t)value;
2841 		break;
2842 	case 2:
2843 		{
2844 			Half	v = (Half)value;
2845 			uchar_t	*v_bytes = (uchar_t *)&v;
2846 
2847 			if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
2848 				UL_ASSIGN_BSWAP_HALF(data, v_bytes);
2849 			} else {
2850 				UL_ASSIGN_HALF(data, v_bytes);
2851 			}
2852 		}
2853 		break;
2854 	case 4:
2855 		{
2856 			Word	v = (Word)value;
2857 			uchar_t	*v_bytes = (uchar_t *)&v;
2858 
2859 			if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
2860 				UL_ASSIGN_BSWAP_WORD(data, v_bytes);
2861 			} else {
2862 				UL_ASSIGN_WORD(data, v_bytes);
2863 			}
2864 		}
2865 		break;
2866 	default:
2867 		{
2868 			Conv_inv_buf_t inv_buf;
2869 			eprintf(ofl->ofl_lml, ERR_FATAL,
2870 			    MSG_INTL(MSG_REL_UNSUPSZ),
2871 			    conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
2872 			    0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
2873 			    (rsp->rel_sname ? demangle(rsp->rel_sname) :
2874 			    MSG_INTL(MSG_STR_UNKNOWN)), (int)rep->re_fsize);
2875 		}
2876 		return (0);
2877 	}
2878 	return (1);
2879 }
2880 
2881 
2882 /*
2883  * Because of the combinations of 32-bit lib providing 64-bit support, and
2884  * visa-versa, the use of krtld's dorelocs can result in differing message
2885  * requirements that make msg.c/msg.h creation and chkmsg "interesting".
2886  * Thus the actual message files contain a couple of entries to satisfy
2887  * each architectures build.  Here we add dummy calls to quieten chkmsg.
2888  *
2889  * chkmsg: MSG_INTL(MSG_REL_NOFIT)
2890  * chkmsg: MSG_INTL(MSG_REL_NONALIGN)
2891  */
2892