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