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