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