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