xref: /titanic_50/usr/src/cmd/sgs/libld/common/relocate.c (revision 789d94c2889bedf502063bc22addcabfa798a438)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  *	Copyright (c) 1988 AT&T
25  *	  All Rights Reserved
26  *
27  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
28  * Use is subject to license terms.
29  */
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 /*
33  * set-up for relocations
34  */
35 #include	<string.h>
36 #include	<stdio.h>
37 #include	<alloca.h>
38 #include	"debug.h"
39 #include	"reloc.h"
40 #include	"msg.h"
41 #include	"_libld.h"
42 
43 /*
44  * Structure to hold copy relocation items.
45  */
46 typedef struct copy_rel {
47 	Sym_desc *	copyrel_symd;	/* symbol descriptor to be copied */
48 	Addr 		copyrel_stval;	/* Original symbol value */
49 } Copy_rel;
50 
51 /*
52  * For each copy relocation symbol, determine if the symbol is:
53  * 	1) to be *disp* relocated at runtime
54  *	2) a reference symbol for *disp* relocation
55  *	3) possibly *disp* relocated at ld time.
56  *
57  * The first and the second are serious errors.
58  */
59 static void
60 is_disp_copied(Ofl_desc *ofl, Copy_rel *cpy)
61 {
62 	Ifl_desc	*ifl = cpy->copyrel_symd->sd_file;
63 	Sym_desc	*sdp = cpy->copyrel_symd;
64 	Is_desc		*irel;
65 	Addr		symaddr = cpy->copyrel_stval;
66 	Listnode	*lnp1;
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(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
76 		    conv_reloc_type_str(ifl->ifl_ehdr->e_machine, M_R_COPY),
77 		    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(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
132 				    conv_reloc_type_str(
133 				    ifl->ifl_ehdr->e_machine,
134 				    (uint_t)ELF_R_TYPE(reloc->r_info)),
135 				    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(ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
161 			    conv_reloc_type_str(ifl->ifl_ehdr->e_machine,
162 			    (uint_t)ELF_R_TYPE(reloc->r_info)), ifl->ifl_name,
163 			    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 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(ERR_WARNING, msg, conv_reloc_type_str(ifl->ifl_ehdr->e_machine,
311 	    rsp->rel_rtype), ifl->ifl_name, rsp->rel_sname, str,
312 	    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_shndx == SHN_UNDEF) ||
370 			    (sdp->sd_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 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 			disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl);
496 	}
497 
498 	DBG_CALL(Dbg_reloc_ars_entry(M_MACH, arsp));
499 	return (1);
500 }
501 
502 uintptr_t
503 reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
504 {
505 	Sym_desc	*sdp;
506 	Word		flags = ofl->ofl_flags;
507 	Gotndx		*gnp;
508 
509 	sdp = rsp->rel_sym;
510 
511 	/*
512 	 * If this is the first time we've seen this symbol in a GOT
513 	 * relocation we need to assign it a GOT token.  Once we've got
514 	 * all of the GOT's assigned we can assign the actual indexes.
515 	 */
516 	if ((gnp = find_gotndx(&(sdp->sd_GOTndxs), GOT_REF_GENERIC,
517 	    ofl, rsp)) == 0) {
518 		Word	rtype = rsp->rel_rtype;
519 
520 		if (assign_gotndx(&(sdp->sd_GOTndxs), 0, GOT_REF_GENERIC,
521 		    ofl, rsp, sdp) == S_ERROR)
522 			return (S_ERROR);
523 
524 		/*
525 		 * Now we initialize the GOT table entry.
526 		 *
527 		 * Pseudo code to describe the the decisions below:
528 		 *
529 		 * If (local)
530 		 * then
531 		 *	enter symbol value in GOT table entry
532 		 *	if (Shared Object)
533 		 *	then
534 		 *		create Relative relocation against symbol
535 		 *	fi
536 		 * else
537 		 *	clear GOT table entry
538 		 *	create a GLOB_DAT relocation against symbol
539 		 * fi
540 		 */
541 		if (local == TRUE) {
542 			if (flags & FLG_OF_SHAROBJ) {
543 				if (add_actrel((FLG_REL_GOT | FLG_REL_GOTCL),
544 				    rsp, ofl) == S_ERROR)
545 					return (S_ERROR);
546 
547 				/*
548 				 * Add a RELATIVE relocation if this is
549 				 * anything but a ABS symbol.
550 				 */
551 				if ((((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
552 				    (sdp->sd_shndx != SHN_ABS)) ||
553 				    (sdp->sd_aux && sdp->sd_aux->sa_symspec)) {
554 					rsp->rel_rtype = M_R_RELATIVE;
555 					if (add_outrel((FLG_REL_GOT |
556 					    FLG_REL_ADVAL), rsp,
557 					    ofl) == S_ERROR)
558 						return (S_ERROR);
559 					rsp->rel_rtype = rtype;
560 				}
561 			} else {
562 				if (add_actrel(FLG_REL_GOT, rsp,
563 				    ofl) == S_ERROR)
564 					return (S_ERROR);
565 			}
566 		} else {
567 			rsp->rel_rtype = M_R_GLOB_DAT;
568 			if (add_outrel(FLG_REL_GOT, rsp, ofl) == S_ERROR)
569 				return (S_ERROR);
570 			rsp->rel_rtype = rtype;
571 		}
572 	} else {
573 		if (assign_gotndx(&(sdp->sd_GOTndxs), gnp, GOT_REF_GENERIC,
574 		    ofl, rsp, sdp) == S_ERROR)
575 			return (S_ERROR);
576 	}
577 
578 	/*
579 	 * Perform relocation to GOT table entry.
580 	 */
581 	return (add_actrel(NULL, rsp, ofl));
582 }
583 
584 
585 /*
586  * Perform relocations for PLT's
587  */
588 uintptr_t
589 reloc_plt(Rel_desc *rsp, Ofl_desc *ofl)
590 {
591 	Sym_desc	*sdp = rsp->rel_sym;
592 
593 #if defined(__i386) || defined(__amd64)
594 #if defined(_ELF64)
595 	/*
596 	 * AMD64 TLS code sequences do not use a unique
597 	 * TLS relocation to reference the __tls_get_addr()
598 	 * 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 (add_actrel(FLG_REL_TLSFIX, rsp, ofl));
603 	}
604 #else
605 	/*
606 	 * GNUC IA32 TLS code sequences do not use a unique
607 	 * TLS relocation to reference the ___tls_get_addr()
608 	 * function call.
609 	 */
610 	if ((ofl->ofl_flags & FLG_OF_EXEC) &&
611 	    (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) == 0)) {
612 		return (add_actrel(FLG_REL_TLSFIX, rsp, ofl));
613 	}
614 #endif
615 #endif	/* __i386 && __amd64 */
616 
617 	/*
618 	 * if (not PLT yet assigned)
619 	 * then
620 	 *	assign PLT index to symbol
621 	 *	build output JMP_SLOT relocation
622 	 * fi
623 	 */
624 	if (sdp->sd_aux->sa_PLTndx == 0) {
625 		Word	ortype = rsp->rel_rtype;
626 
627 		assign_plt_ndx(sdp, ofl);
628 
629 		/*
630 		 * If this symbol is binding to a LAZYLOADED object then
631 		 * set the LAZYLD symbol flag.
632 		 */
633 		if ((sdp->sd_aux->sa_bindto &&
634 		    (sdp->sd_aux->sa_bindto->ifl_flags & FLG_IF_LAZYLD)) ||
635 		    (sdp->sd_file &&
636 		    (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD)))
637 			sdp->sd_flags |= FLG_SY_LAZYLD;
638 
639 		rsp->rel_rtype = M_R_JMP_SLOT;
640 		if (add_outrel(FLG_REL_PLT, rsp, ofl) == S_ERROR)
641 			return (S_ERROR);
642 		rsp->rel_rtype = ortype;
643 	}
644 
645 	/*
646 	 * Perform relocation to PLT table entry.
647 	 */
648 	if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
649 	    IS_ADD_RELATIVE(rsp->rel_rtype)) {
650 		Word	ortype	= rsp->rel_rtype;
651 
652 		rsp->rel_rtype = M_R_RELATIVE;
653 		if (add_outrel(FLG_REL_ADVAL, rsp, ofl) == S_ERROR)
654 			return (S_ERROR);
655 		rsp->rel_rtype = ortype;
656 		return (1);
657 	} else
658 		return (add_actrel(NULL, rsp, ofl));
659 }
660 
661 /*
662  * process GLOBAL undefined and ref_dyn_need symbols.
663  */
664 uintptr_t
665 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl)
666 {
667 	Sym_desc	*_sdp, *sdp = rsp->rel_sym;
668 	Sym_aux		*sap = sdp->sd_aux;
669 	Sym		*sym = sdp->sd_sym;
670 	Addr		stval;
671 
672 	/*
673 	 * Reference is to a function so simply create a plt entry for it.
674 	 */
675 	if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
676 		return (reloc_plt(rsp, ofl));
677 
678 	/*
679 	 * Catch absolutes - these may cause a text relocation.
680 	 */
681 	if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sdp->sd_shndx == SHN_ABS)) {
682 		if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0)
683 			return (add_outrel(NULL, rsp, ofl));
684 		/*
685 		 * If -zabsexec is set then promote the ABSOLUTE
686 		 * symbol to current the current object and
687 		 * perform the relocation now.
688 		 */
689 		sdp->sd_ref = REF_REL_NEED;
690 		return (add_actrel(NULL, rsp, ofl));
691 	}
692 
693 	/*
694 	 * If the relocation is against a writable section simply compute the
695 	 * necessary output relocation.  As an optimization, if the symbol has
696 	 * already been transformed into a copy relocation then we can perform
697 	 * the relocation directly (copy relocations should only be generated
698 	 * for references from the text segment and these relocations are
699 	 * normally carried out before we get to the data segment relocations).
700 	 */
701 	if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) &&
702 	    (rsp->rel_osdesc->os_shdr->sh_flags & SHF_WRITE)) {
703 		if (sdp->sd_flags & FLG_SY_MVTOCOMM)
704 			return (add_actrel(NULL, rsp, ofl));
705 		else
706 			return (add_outrel(NULL, rsp, ofl));
707 	}
708 
709 	/*
710 	 * If the reference isn't to an object (normally because some idiot
711 	 * hasn't defined a .type directive in some assembler source), then
712 	 * simply apply a generic relocation (this has a tendency to result in
713 	 * text relocations).
714 	 */
715 	if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) {
716 		eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
717 		    conv_info_type_str(ofl->ofl_e_machine,
718 		    ELF_ST_TYPE(sym->st_info)),
719 		    rsp->rel_isdesc->is_file->ifl_name,
720 		    demangle(rsp->rel_sname), sdp->sd_file->ifl_name);
721 		return (add_outrel(NULL, rsp, ofl));
722 	}
723 
724 	/*
725 	 * Prepare for generating a copy relocation.
726 	 *
727 	 * If this symbol is one of an alias pair, we need to insure both
728 	 * symbols become part of the output (the strong symbol will be used to
729 	 * maintain the symbols state).  And, if we did raise the precedence of
730 	 * a symbol we need to check and see if this is a weak symbol.  If it is
731 	 * we want to use it's strong counter part.
732 	 *
733 	 * The results of this logic should be:
734 	 *	rel_usym: assigned to strong
735 	 *	 rel_sym: assigned to symbol to perform
736 	 *		  copy_reloc against (weak or strong).
737 	 */
738 	if (sap->sa_linkndx) {
739 		_sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
740 
741 		if (_sdp->sd_ref < sdp->sd_ref) {
742 			_sdp->sd_ref = sdp->sd_ref;
743 			_sdp->sd_flags |= FLG_SY_REFRSD;
744 
745 			/*
746 			 * As we're going to replicate a symbol from a shared
747 			 * object, retain its correct binding status.
748 			 */
749 			if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL)
750 				_sdp->sd_flags |= FLG_SY_GLOBREF;
751 
752 		} else if (_sdp->sd_ref > sdp->sd_ref) {
753 			sdp->sd_ref = _sdp->sd_ref;
754 			sdp->sd_flags |= FLG_SY_REFRSD;
755 
756 			/*
757 			 * As we're going to replicate a symbol from a shared
758 			 * object, retain its correct binding status.
759 			 */
760 			if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL)
761 				sdp->sd_flags |= FLG_SY_GLOBREF;
762 		}
763 
764 		/*
765 		 * If this is a weak symbol then we want to move the strong
766 		 * symbol into local .bss.  If there is a copy_reloc to be
767 		 * performed, that should still occur against the WEAK symbol.
768 		 */
769 		if ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
770 		    (sdp->sd_flags & FLG_SY_WEAKDEF))
771 			rsp->rel_usym = _sdp;
772 	} else
773 		_sdp = 0;
774 
775 	/*
776 	 * If the reference is to an object then allocate space for the object
777 	 * within the executables .bss.  Relocations will now be performed from
778 	 * this new location.  If the original shared objects data is
779 	 * initialized, then generate a copy relocation that will copy the data
780 	 * to the executables .bss at runtime.
781 	 */
782 	if (!(rsp->rel_usym->sd_flags & FLG_SY_MVTOCOMM)) {
783 		Word	rtype = rsp->rel_rtype;
784 		Copy_rel *cpy_rel;
785 
786 		/*
787 		 * Indicate that the symbol(s) against which we're relocating
788 		 * have been moved to the executables common.  Also, insure that
789 		 * the symbol(s) remain marked as global, as the shared object
790 		 * from which they are copied must be able to relocate to the
791 		 * new common location within the executable.
792 		 *
793 		 * Note that even though a new symbol has been generated in the
794 		 * output files' .bss, the symbol must remain REF_DYN_NEED and
795 		 * not be promoted to REF_REL_NEED.  sym_validate() still needs
796 		 * to carry out a number of checks against the symbols binding
797 		 * that are triggered by the REF_DYN_NEED state.
798 		 */
799 		sdp->sd_flags |= FLG_SY_MVTOCOMM;
800 		sdp->sd_flags1 |= FLG_SY1_GLOB;
801 		sdp->sd_flags1 &= ~FLG_SY1_LOCL;
802 		sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
803 		if (_sdp) {
804 			_sdp->sd_flags |= FLG_SY_MVTOCOMM;
805 			_sdp->sd_flags1 |= FLG_SY1_GLOB;
806 			_sdp->sd_flags1 &= ~FLG_SY1_LOCL;
807 			_sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
808 
809 			/*
810 			 * Make sure the symbol has a reference in case of any
811 			 * error diagnostics against it (perhaps this belongs
812 			 * to a version that isn't allowable for this build).
813 			 * The resulting diagnostic (see sym_undef_entry())
814 			 * might seem a little bogus, as the symbol hasn't
815 			 * really been referenced by this file, but has been
816 			 * promoted as a consequence of its alias reference.
817 			 */
818 			if (!(_sdp->sd_aux->sa_rfile))
819 				_sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile;
820 		}
821 
822 		/*
823 		 * Assign the symbol to the bss and insure sufficient alignment
824 		 * (we don't know the real alignment so we have to make the
825 		 * worst case guess).
826 		 */
827 		_sdp = rsp->rel_usym;
828 		stval = _sdp->sd_sym->st_value;
829 		if (sym_copy(_sdp) == S_ERROR)
830 			return (S_ERROR);
831 		_sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON;
832 		_sdp->sd_flags |= FLG_SY_SPECSEC;
833 		_sdp->sd_sym->st_value =
834 		    (_sdp->sd_sym->st_size < (M_WORD_ALIGN * 2)) ?
835 		    M_WORD_ALIGN : M_WORD_ALIGN * 2;
836 
837 		/*
838 		 * Whether or not the symbol references initialized
839 		 * data we generate a copy relocation - this differs
840 		 * from the past where we would not create the COPY_RELOC
841 		 * if we were binding against .bss.  This is done
842 		 * for *two* reasons.
843 		 *
844 		 *  o If the symbol in the shared object changes to
845 		 *    a initialized data - we need the COPY to pick it
846 		 *    up.
847 		 *  o without the COPY RELOC we can't tell that the
848 		 *    symbol from the COPY'd object has been moved
849 		 *    and all bindings to it should bind here.
850 		 */
851 
852 		/*
853 		 * Keep this symbol in the copy relocation list
854 		 * to check the validity later.
855 		 */
856 		if ((cpy_rel = libld_malloc(sizeof (Copy_rel))) == 0)
857 			return (S_ERROR);
858 		cpy_rel->copyrel_symd = _sdp;
859 		cpy_rel->copyrel_stval = stval;
860 		if (list_appendc(&ofl->ofl_copyrels, cpy_rel) == 0)
861 			return (S_ERROR);
862 
863 		rsp->rel_rtype = M_R_COPY;
864 		if (add_outrel(FLG_REL_BSS, rsp, ofl) == S_ERROR)
865 			return (S_ERROR);
866 		rsp->rel_rtype = rtype;
867 
868 		/*
869 		 * If this symbol is a protected symbol, warn it.
870 		 */
871 		if (_sdp->sd_flags & FLG_SY_PROT)
872 			eprintf(ERR_WARNING, MSG_INTL(MSG_REL_COPY),
873 			conv_reloc_type_str(_sdp->sd_file->ifl_ehdr->e_machine,
874 			M_R_COPY), _sdp->sd_file->ifl_name, _sdp->sd_name);
875 		DBG_CALL(Dbg_syms_reloc(sdp->sd_file->ifl_ehdr, sdp));
876 	}
877 	return (add_actrel(NULL, rsp, ofl));
878 }
879 
880 /*
881  * All relocations should have been handled by the other routines.  This
882  * routine is hear 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 uintptr_t
886 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl)
887 {
888 	Word	flags = ofl->ofl_flags;
889 
890 	eprintf(ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
891 	    conv_reloc_type_str(ofl->ofl_e_machine, rsp->rel_rtype),
892 	    rsp->rel_isdesc->is_file->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 (flags & FLG_OF_SHAROBJ)
899 		return (add_outrel(NULL, rsp, ofl));
900 
901 	/*
902 	 * Otherwise process relocation now.
903 	 */
904 	return (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 (add_actrel(NULL, rsp, ofl));
931 
932 	/*
933 	 * If -zredlocsym is in effect, translate all local symbol relocations
934 	 * to be against section symbols, since section symbols are the only
935 	 * 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(ERR_FATAL, MSG_INTL(MSG_REL_PICREDLOC),
948 			    demangle(rsp->rel_sname), ifl->ifl_name,
949 			    conv_reloc_type_str(ifl->ifl_ehdr->e_machine,
950 			    rsp->rel_rtype));
951 			return (S_ERROR);
952 		}
953 
954 		/*
955 		 * Indicate that this relocation should be processed the same
956 		 * as a section symbol.  For SPARC and AMD (Rela), indicate
957 		 * that the addend also needs to be applied to this relocation.
958 		 */
959 #if	(defined(__i386) || defined(__amd64)) && !defined(_ELF64)
960 		oflags = FLG_REL_SCNNDX;
961 #else
962 		oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL;
963 #endif
964 	}
965 
966 #if	(defined(__i386) || defined(__amd64)) && !defined(_ELF64)
967 	/*
968 	 * Intel (Rel) relocations do not contain an addend.  Any addend is
969 	 * contained within the file at the location identified by the
970 	 * relocation offset.  Therefore, if we're processing a section symbol,
971 	 * or a -zredlocsym relocation (that basically transforms a local symbol
972 	 * reference into a section reference), perform an active relocation to
973 	 * propagate any addend.
974 	 */
975 	if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) ||
976 	    (oflags == FLG_REL_SCNNDX))
977 		if (add_actrel(NULL, rsp, ofl) == S_ERROR)
978 			return (S_ERROR);
979 #endif
980 	return (add_outrel(oflags, rsp, ofl));
981 }
982 
983 uintptr_t
984 process_sym_reloc(Ofl_desc * ofl, Rel_desc * reld, Rel * reloc,
985     Is_desc * isp, const char *isname)
986 {
987 	Word		rtype = reld->rel_rtype;
988 	Word		flags = ofl->ofl_flags;
989 	Sym_desc	*sdp = reld->rel_sym;
990 	Sym_aux		*sap;
991 	Boolean		local;
992 
993 	DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc,
994 	    reld->rel_sname, isname));
995 
996 	/*
997 	 * Indicate this symbol is being used for relocation and therefore must
998 	 * have its output address updated accordingly (refer to update_osym()).
999 	 */
1000 	sdp->sd_flags |= FLG_SY_UPREQD;
1001 
1002 	/*
1003 	 * Indicate the section this symbol is defined in has been referenced,
1004 	 * therefor it *is not* a candidate for elimination.
1005 	 */
1006 	if (sdp->sd_isc) {
1007 		sdp->sd_isc->is_flags |= FLG_IS_SECTREF;
1008 		sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF;
1009 	}
1010 
1011 	reld->rel_usym = sdp;
1012 
1013 	/*
1014 	 * Determine if this symbol is actually an alias to another symbol.  If
1015 	 * so, and the alias is not REF_DYN_SEEN, set rel_usym to point to the
1016 	 * weak symbols strong counter-part.  The one exception is if the
1017 	 * FLG_SY_MVTOCOMM flag is set on the weak symbol.  If this is the case,
1018 	 * the strong is only here because of its promotion, and the weak symbol
1019 	 * should still be used for the relocation reference (see reloc_exec()).
1020 	 */
1021 	sap = sdp->sd_aux;
1022 	if (sap && sap->sa_linkndx &&
1023 	    ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1024 	    (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1025 	    (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) {
1026 		Sym_desc *	_sdp;
1027 
1028 		_sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1029 		if (_sdp->sd_ref != REF_DYN_SEEN)
1030 			reld->rel_usym = _sdp;
1031 	}
1032 
1033 	/*
1034 	 * Determine whether this symbol should be bound locally or not.
1035 	 * Symbols will be bound locally if one of the following is true:
1036 	 *
1037 	 *  o	the symbol is of type STB_LOCAL
1038 	 *
1039 	 *  o	the output image is not a relocatable object and the
1040 	 *	relocation is relative to the .got
1041 	 *
1042 	 *  o	the section being relocated is of type SHT_SUNW_dof;
1043 	 *	these sections are bound to the functions in the
1044 	 *	containing object and don't care about interpositioning
1045 	 *
1046 	 *  o	the symbol has been reduced (scoped to a local or
1047 	 *	symbolic) and reductions are being processed
1048 	 *
1049 	 *  o	the -Bsymbolic flag is in use when building a shared
1050 	 *	object or an executable (fixed address) is being created
1051 	 *
1052 	 *  o	Building an executable and the symbol is defined
1053 	 *	in the executable.
1054 	 *
1055 	 *  o	the relocation is against a segment which will not
1056 	 *	be loaded into memory.  If that is the case we need
1057 	 *	to resolve the relocation now because ld.so.1 won't
1058 	 *	be able to.
1059 	 */
1060 	local = FALSE;
1061 	if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1062 		local = TRUE;
1063 	} else if (!(reld->rel_flags & FLG_REL_LOAD)) {
1064 		local = TRUE;
1065 	} else if (sdp->sd_shndx != SHN_UNDEF) {
1066 		if (reld->rel_isdesc &&
1067 		    reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) {
1068 			local = TRUE;
1069 		} else if (!(flags & FLG_OF_RELOBJ) &&
1070 		    (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) {
1071 			local = TRUE;
1072 		} else if (sdp->sd_ref == REF_REL_NEED) {
1073 			if ((sdp->sd_flags1 & (FLG_SY1_LOCL | FLG_SY1_PROT)))
1074 				local = TRUE;
1075 			else if (flags & (FLG_OF_SYMBOLIC | FLG_OF_EXEC))
1076 				local = TRUE;
1077 		}
1078 	}
1079 
1080 	/*
1081 	 * If this is a PC_RELATIVE relocation, the relocation could be
1082 	 * compromised if the relocated address is later used as a copy
1083 	 * relocated symbol (PSARC 1999/636, bugid 4187211).  Scan the input
1084 	 * files symbol table to cross reference this relocation offset.
1085 	 */
1086 	if ((ofl->ofl_flags & FLG_OF_SHAROBJ) && IS_PC_RELATIVE(rtype) &&
1087 	    (IS_GOT_PC(rtype) == 0) && (IS_PLT(rtype) == 0)) {
1088 		if (disp_inspect(ofl, reld, local) == S_ERROR)
1089 			return (S_ERROR);
1090 	}
1091 
1092 	/*
1093 	 * GOT based relocations must bind to the object being built - since
1094 	 * they are relevant to the current GOT.  If not building a relocatable
1095 	 * object - give a appropriate error message.
1096 	 */
1097 	if (!local && !(flags & FLG_OF_RELOBJ) && IS_GOT_BASED(rtype)) {
1098 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
1099 		    conv_reloc_type_str(ofl->ofl_e_machine, rtype),
1100 		    reld->rel_isdesc->is_file->ifl_name,
1101 		    demangle(sdp->sd_name));
1102 		return (S_ERROR);
1103 	}
1104 
1105 	/*
1106 	 * TLS symbols can only have TLS relocations.
1107 	 */
1108 	if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) && !IS_TLS(rtype)) {
1109 		/*
1110 		 * The above test is relaxed if the target section is
1111 		 * non-allocable.
1112 		 */
1113 		if (reld->rel_osdesc->os_shdr->sh_flags & SHF_ALLOC) {
1114 			eprintf(ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
1115 			    conv_reloc_type_str(ofl->ofl_e_machine, rtype),
1116 			    reld->rel_isdesc->is_file->ifl_name,
1117 			    demangle(sdp->sd_name));
1118 			return (S_ERROR);
1119 		}
1120 	}
1121 
1122 	/*
1123 	 * Select the relocation to perform.
1124 	 */
1125 	if (IS_REGISTER(rtype))
1126 		return (reloc_register(reld, isp, ofl));
1127 
1128 	if (flags & FLG_OF_RELOBJ)
1129 		return (reloc_relobj(local, reld, ofl));
1130 
1131 	if (IS_TLS_INS(rtype))
1132 		return (reloc_TLS(local, reld, ofl));
1133 
1134 	if (IS_GOT_INS(rtype))
1135 		return (reloc_GOTOP(local, reld, ofl));
1136 
1137 	if (IS_GOT_RELATIVE(rtype))
1138 		return (reloc_GOT_relative(local, reld, ofl));
1139 
1140 	if (local)
1141 		return (reloc_local(reld, ofl));
1142 
1143 	if ((IS_PLT(rtype)) && ((flags & FLG_OF_BFLAG) == 0))
1144 		return (reloc_plt(reld, ofl));
1145 
1146 	if ((sdp->sd_ref == REF_REL_NEED) ||
1147 	    (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) ||
1148 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE))
1149 		return (add_outrel(NULL, reld, ofl));
1150 
1151 	if (sdp->sd_ref == REF_DYN_NEED)
1152 		return (reloc_exec(reld, ofl));
1153 
1154 	/*
1155 	 * IS_NOT_REL(rtype)
1156 	 */
1157 	return (reloc_generic(reld, ofl));
1158 }
1159 
1160 /*
1161  * Generate relocation descriptor and dispatch
1162  */
1163 static uintptr_t
1164 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
1165     Rel *reloc)
1166 {
1167 	Ifl_desc	*ifl = isp->is_file;
1168 	Word		rtype = reld->rel_rtype;
1169 	Sym_desc	*sdp;
1170 
1171 	/*
1172 	 * Make sure the relocation is in the valid range.
1173 	 */
1174 	if (rtype >= M_R_NUM) {
1175 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT), ifl->ifl_name,
1176 		    isp->is_name, rtype);
1177 		return (S_ERROR);
1178 	}
1179 
1180 	ofl->ofl_entrelscnt++;
1181 
1182 	/*
1183 	 * Special case: a register symbol associated with symbol index 0 is
1184 	 * initialized (i.e., relocated) to a constant from the r_addend field
1185 	 * rather than from a symbol value.
1186 	 */
1187 	if (IS_REGISTER(rtype) && (rsndx == 0)) {
1188 		reld->rel_sym = 0;
1189 		reld->rel_sname = MSG_ORIG(MSG_STR_EMPTY);
1190 
1191 		DBG_CALL(Dbg_reloc_in(M_MACH, isp->is_shdr->sh_type,
1192 		    (void *)reloc, reld->rel_sname, isp->is_name));
1193 		return (reloc_register(reld, isp, ofl));
1194 	}
1195 
1196 	/*
1197 	 * Determine whether we're dealing with a named symbol.  Note, bogus
1198 	 * relocations can result in a null symbol descriptor (sdp), the error
1199 	 * condition should be caught below after determining whether a valid
1200 	 * symbol name exists.
1201 	 */
1202 	sdp = ifl->ifl_oldndx[rsndx];
1203 	if (sdp != NULL && sdp->sd_name && *sdp->sd_name)
1204 		reld->rel_sname = sdp->sd_name;
1205 	else {
1206 		static char *strunknown;
1207 
1208 		if (strunknown == 0)
1209 			strunknown = (char *)MSG_INTL(MSG_STR_UNKNOWN);
1210 		reld->rel_sname = strunknown;
1211 	}
1212 
1213 	/*
1214 	 * If for some reason we have a null relocation record issue a
1215 	 * warning and continue (the compiler folks can get into this
1216 	 * state some time).  Normal users should never see this error.
1217 	 */
1218 	if (rtype == M_R_NONE) {
1219 		DBG_CALL(Dbg_reloc_in(M_MACH, M_REL_SHT_TYPE, (void *)reloc,
1220 		    reld->rel_sname, isp->is_name));
1221 		eprintf(ERR_WARNING, MSG_INTL(MSG_REL_NULL), ifl->ifl_name,
1222 		    isp->is_name);
1223 		return (1);
1224 	}
1225 
1226 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) && IS_NOTSUP(rtype)) {
1227 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
1228 		    conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype),
1229 		    ifl->ifl_name, isp->is_name);
1230 		return (S_ERROR);
1231 	}
1232 
1233 	/*
1234 	 * If we are here, we know that the relocation requires reference
1235 	 * symbol. If no symbol is assigned, this is a fatal error.
1236 	 */
1237 	if (sdp == NULL) {
1238 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
1239 		    conv_reloc_type_str(ifl->ifl_ehdr->e_machine, rtype),
1240 		    isp->is_name, ifl->ifl_name, EC_XWORD(reloc->r_offset));
1241 		return (S_ERROR);
1242 	}
1243 
1244 	if (sdp->sd_flags1 & FLG_SY1_IGNORE)
1245 		return (1);
1246 
1247 	/*
1248 	 * If this symbol is part of a DISCARDED section attempt to find another
1249 	 * definition.
1250 	 */
1251 	if (sdp->sd_flags & FLG_SY_ISDISC) {
1252 		Sym_desc *	nsdp;
1253 
1254 		if ((reld->rel_sname != sdp->sd_name) ||
1255 		    (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) ||
1256 		    ((nsdp = sym_find(sdp->sd_name, SYM_NOHASH, 0,
1257 		    ofl)) == 0)) {
1258 			eprintf(ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC),
1259 			    ifl->ifl_name, isp->is_name, demangle(sdp->sd_name),
1260 			    sdp->sd_isc->is_name);
1261 			return (S_ERROR);
1262 		}
1263 		ifl->ifl_oldndx[rsndx] = sdp = nsdp;
1264 	}
1265 
1266 	/*
1267 	 * If this is a global symbol, determine whether its visibility needs
1268 	 * adjusting.
1269 	 */
1270 	if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0))
1271 		sym_adjust_vis(sdp, ofl);
1272 
1273 	/*
1274 	 * Ignore any relocation against a section that will not be in the
1275 	 * output file (has been stripped).
1276 	 */
1277 	if ((sdp->sd_isc == 0) &&
1278 	    (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))
1279 		return (1);
1280 
1281 	/*
1282 	 * If the symbol for this relocation is invalid (which should have
1283 	 * generated a message during symbol processing), or the relocation
1284 	 * record's symbol reference is in any other way invalid, then it's
1285 	 * about time we gave up.
1286 	 */
1287 	if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
1288 	    (rsndx >= ifl->ifl_symscnt)) {
1289 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
1290 		    M_REL_CONTYPSTR(rtype), ifl->ifl_name, isp->is_name,
1291 		    demangle(reld->rel_sname), EC_XWORD(reloc->r_offset),
1292 		    EC_WORD(rsndx));
1293 		return (S_ERROR);
1294 	}
1295 
1296 	reld->rel_sym = sdp;
1297 	return (process_sym_reloc(ofl, reld, reloc, isp, isp->is_name));
1298 }
1299 
1300 static uintptr_t
1301 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect)
1302 {
1303 	Rel		*rend;		/* end of relocation section data */
1304 	Rel		*reloc;		/* current relocation entry */
1305 	Xword		rsize;		/* size of relocation section data */
1306 	Xword		entsize;	/* size of relocation entry */
1307 	Rel_desc	reld;		/* relocation descriptor */
1308 	Shdr *		shdr;
1309 	Word		flags = 0;
1310 
1311 	shdr = rsect->is_shdr;
1312 	rsize = shdr->sh_size;
1313 	reloc = (Rel *)rsect->is_indata->d_buf;
1314 
1315 	/*
1316 	 * Decide entry size.
1317 	 */
1318 	if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) {
1319 		if (shdr->sh_type == SHT_RELA)
1320 			entsize = sizeof (Rela);
1321 		else
1322 			entsize = sizeof (Rel);
1323 	}
1324 
1325 	/*
1326 	 * Build up the basic information in for the Rel_desc structure.
1327 	 */
1328 	reld.rel_osdesc = osect;
1329 	reld.rel_isdesc = isect;
1330 	reld.rel_move = 0;
1331 
1332 	if ((ofl->ofl_flags & FLG_OF_RELOBJ) ||
1333 	    (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD)))
1334 		flags |= FLG_REL_LOAD;
1335 
1336 	if (shdr->sh_info == 0)
1337 		flags |= FLG_REL_NOINFO;
1338 
1339 	DBG_CALL(Dbg_reloc_proc(osect, isect, rsect));
1340 
1341 	for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
1342 	    reloc < rend;
1343 	    reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
1344 		Word	rsndx;
1345 
1346 		/*
1347 		 * Initialize the relocation record information and process
1348 		 * the individual relocation.  Reinitialize the flags to
1349 		 * insure we don't carry any state over from the previous
1350 		 * relocation records processing.
1351 		 */
1352 		reld.rel_flags = flags;
1353 		rsndx = init_rel(&reld, (void *)reloc);
1354 
1355 		if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR)
1356 			return (S_ERROR);
1357 	}
1358 	return (1);
1359 }
1360 
1361 
1362 uintptr_t
1363 reloc_segments(int wr_flag, Ofl_desc *ofl)
1364 {
1365 	Listnode	*lnp1;
1366 	Sg_desc		*sgp;
1367 	Is_desc		*isp;
1368 
1369 	for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {
1370 		Os_desc		*osp;
1371 		Listnode	*lnp2;
1372 
1373 		if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag)
1374 			continue;
1375 
1376 		for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) {
1377 			Is_desc		*risp;
1378 			Listnode	*lnp3;
1379 
1380 			osp->os_szoutrels = 0;
1381 			for (LIST_TRAVERSE(&(osp->os_relisdescs), lnp3, risp)) {
1382 				Word	indx;
1383 
1384 				/*
1385 				 * Determine the input section that this
1386 				 * relocation information refers to.
1387 				 */
1388 				indx = risp->is_shdr->sh_info;
1389 				isp = risp->is_file->ifl_isdesc[indx];
1390 
1391 				/*
1392 				 * Do not process relocations against sections
1393 				 * which are being discarded (COMDAT)
1394 				 */
1395 				if (isp->is_flags & FLG_IS_DISCARD)
1396 					continue;
1397 
1398 				if (reloc_section(ofl, isp, risp, osp) ==
1399 				    S_ERROR)
1400 					return (S_ERROR);
1401 			}
1402 
1403 			/*
1404 			 * Check for relocations against non-writable
1405 			 * allocatable sections.
1406 			 */
1407 			if ((osp->os_szoutrels) &&
1408 			    (sgp->sg_phdr.p_type == PT_LOAD) &&
1409 			    ((sgp->sg_phdr.p_flags & PF_W) == 0)) {
1410 				ofl->ofl_flags |= FLG_OF_TEXTREL;
1411 				ofl->ofl_dtflags |= DF_TEXTREL;
1412 			}
1413 		}
1414 	}
1415 
1416 	return (1);
1417 }
1418 
1419 /*
1420  * Move Section related function
1421  * Get move entry
1422  */
1423 static Move *
1424 get_move_entry(Is_desc *rsect, Xword roffset)
1425 {
1426 	Ifl_desc	*ifile = rsect->is_file;
1427 	Shdr		*rshdr = rsect->is_shdr;
1428 	Is_desc		*misp;
1429 	Shdr		*mshdr;
1430 	Xword 		midx;
1431 	Move		*ret;
1432 
1433 	/*
1434 	 * Set info for the target move section
1435 	 */
1436 	misp = ifile->ifl_isdesc[rshdr->sh_info];
1437 	mshdr = (ifile->ifl_isdesc[rshdr->sh_info])->is_shdr;
1438 
1439 	if (mshdr->sh_entsize == 0)
1440 		return ((Move *)0);
1441 	midx = roffset / mshdr->sh_entsize;
1442 
1443 	ret = (Move *)misp->is_indata->d_buf;
1444 	ret += midx;
1445 
1446 	/*
1447 	 * If this is an illgal entry, retun NULL.
1448 	 */
1449 	if ((midx * mshdr->sh_entsize) >= mshdr->sh_size)
1450 		return ((Move *)0);
1451 	return (ret);
1452 }
1453 
1454 /*
1455  * Relocation against Move Table.
1456  */
1457 static uintptr_t
1458 process_movereloc(Ofl_desc *ofl, Is_desc *rsect)
1459 {
1460 	Ifl_desc	*file = rsect->is_file;
1461 	Rel		*rend, *reloc;
1462 	Xword 		rsize, entsize;
1463 	static Rel_desc reld_zero;
1464 	Rel_desc 	reld;
1465 
1466 	rsize = rsect->is_shdr->sh_size;
1467 	reloc = (Rel *)rsect->is_indata->d_buf;
1468 
1469 	reld = reld_zero;
1470 
1471 	/*
1472 	 * Decide entry size
1473 	 */
1474 	entsize = rsect->is_shdr->sh_entsize;
1475 	if ((entsize == 0) ||
1476 	    (entsize > rsect->is_shdr->sh_size)) {
1477 		if (rsect->is_shdr->sh_type == SHT_RELA)
1478 			entsize = sizeof (Rela);
1479 		else
1480 			entsize = sizeof (Rel);
1481 	}
1482 
1483 	/*
1484 	 * Go through the relocation entries.
1485 	 */
1486 	for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
1487 	    reloc < rend;
1488 	    reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
1489 		Sym_desc *	psdp;
1490 		Move *		mp;
1491 		Word		rsndx;
1492 
1493 		/*
1494 		 * Initialize the relocation record information.
1495 		 */
1496 		reld.rel_flags = FLG_REL_LOAD;
1497 		rsndx = init_rel(&reld, (void *)reloc);
1498 
1499 		if (((mp = get_move_entry(rsect, reloc->r_offset)) == 0) ||
1500 		    ((reld.rel_move = libld_malloc(sizeof (Mv_desc))) == 0))
1501 			return (S_ERROR);
1502 
1503 		psdp = file->ifl_oldndx[ELF_M_SYM(mp->m_info)];
1504 		reld.rel_move->mvd_move = mp;
1505 		reld.rel_move->mvd_sym = psdp;
1506 
1507 		if (psdp->sd_flags & FLG_SY_PAREXPN) {
1508 			int	_num, num;
1509 
1510 			reld.rel_osdesc = ofl->ofl_issunwdata1->is_osdesc;
1511 			reld.rel_isdesc = ofl->ofl_issunwdata1;
1512 			reld.rel_roffset = mp->m_poffset;
1513 
1514 			for (num = mp->m_repeat, _num = 0; _num < num; _num++) {
1515 				reld.rel_roffset +=
1516 					/* LINTED */
1517 					(_num * ELF_M_SIZE(mp->m_info));
1518 				/*
1519 				 * Generate Reld
1520 				 */
1521 				if (process_reld(ofl,
1522 				    rsect, &reld, rsndx, reloc) == S_ERROR)
1523 					return (S_ERROR);
1524 			}
1525 		} else {
1526 			/*
1527 			 * Generate Reld
1528 			 */
1529 			reld.rel_flags |= FLG_REL_MOVETAB;
1530 			reld.rel_osdesc = ofl->ofl_osmove;
1531 			reld.rel_isdesc =
1532 				ofl->ofl_osmove->os_isdescs.head->data;
1533 			if (process_reld(ofl,
1534 			    rsect, &reld, rsndx, reloc) == S_ERROR)
1535 				return (S_ERROR);
1536 		}
1537 	}
1538 	return (1);
1539 }
1540 
1541 /*
1542  * This function is similar to reloc_init().
1543  *
1544  * This function is called when the SHT_SUNW_move table is expanded
1545  * and there were relocation against the SHT_SUNW_move section.
1546  */
1547 static uintptr_t
1548 reloc_movesections(Ofl_desc *ofl)
1549 {
1550 	Listnode	*lnp1;
1551 	Is_desc		*risp;
1552 
1553 	/*
1554 	 * Generate/Expand relocation entries
1555 	 */
1556 	for (LIST_TRAVERSE(&ofl->ofl_mvrelisdescs, lnp1, risp)) {
1557 		if (process_movereloc(ofl, risp) == S_ERROR)
1558 			return (S_ERROR);
1559 	}
1560 
1561 	return (1);
1562 }
1563 
1564 /*
1565  * Count the number of output relocation entries, global offset table entries,
1566  * and procedure linkage table entries.  This function searches the segment and
1567  * outsect lists and passes each input reloc section to process_reloc().
1568  * It allocates space for any output relocations needed.  And builds up
1569  * the relocation structures for later processing.
1570  */
1571 uintptr_t
1572 reloc_init(Ofl_desc *ofl)
1573 {
1574 	Listnode	*lnp;
1575 	Is_desc		*isp;
1576 
1577 	/*
1578 	 * At this point we have finished processing all input symbols.  Make
1579 	 * sure we add any absolute (internal) symbols before continuing with
1580 	 * any relocation processing.
1581 	 */
1582 	if (sym_spec(ofl) == S_ERROR)
1583 		return (S_ERROR);
1584 
1585 	ofl->ofl_gotcnt = M_GOT_XNumber;
1586 
1587 	/*
1588 	 * First process all of the relocations against NON-writable
1589 	 * segments followed by relocations against the writeable segments.
1590 	 *
1591 	 * This separation is so that when the writable segments are processed
1592 	 * we know whether or not a COPYRELOC will be produced for any symbols.
1593 	 * If relocations aren't processed in this order, a COPYRELOC and a
1594 	 * regular relocation can be produced against the same symbol.  The
1595 	 * regular relocation would be redundant.
1596 	 */
1597 	if (reloc_segments(0, ofl) == S_ERROR)
1598 		return (S_ERROR);
1599 
1600 	if (reloc_segments(PF_W, ofl) == S_ERROR)
1601 		return (S_ERROR);
1602 
1603 	/*
1604 	 * Process any extra relocations.  These are relocation sections that
1605 	 * have a NULL sh_info.
1606 	 */
1607 	for (LIST_TRAVERSE(&ofl->ofl_extrarels, lnp, isp)) {
1608 		if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR)
1609 			return (S_ERROR);
1610 	}
1611 
1612 	/*
1613 	 * If there were relocation against move table,
1614 	 * process the relocation sections.
1615 	 */
1616 	if (reloc_movesections(ofl) == S_ERROR)
1617 		return (S_ERROR);
1618 
1619 	/*
1620 	 * Now all the relocations are pre-processed,
1621 	 * check the validity of copy relocations.
1622 	 */
1623 	if (ofl->ofl_copyrels.head != 0) {
1624 		Copy_rel *	cpyrel;
1625 
1626 		for (LIST_TRAVERSE(&ofl->ofl_copyrels, lnp, cpyrel)) {
1627 			Sym_desc *	sdp;
1628 
1629 			sdp = cpyrel->copyrel_symd;
1630 			/*
1631 			 * If there were no displacement relocation
1632 			 * in this file, don't worry about it.
1633 			 */
1634 			if (sdp->sd_file->ifl_flags &
1635 			    (FLG_IF_DISPPEND | FLG_IF_DISPDONE))
1636 				is_disp_copied(ofl, cpyrel);
1637 		}
1638 	}
1639 
1640 	/*
1641 	 * GOT sections are created for dynamic executables and shared objects
1642 	 * if the FLG_OF_BLDGOT is set, or explicit reference has been made to
1643 	 * a GOT symbol.
1644 	 */
1645 	if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
1646 	    ((ofl->ofl_flags & FLG_OF_BLDGOT) ||
1647 	    (sym_find(MSG_ORIG(MSG_SYM_GOFTBL), SYM_NOHASH, 0, ofl) != 0) ||
1648 	    (sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U), SYM_NOHASH, 0, ofl) != 0))) {
1649 		if (make_got(ofl) == S_ERROR)
1650 			return (S_ERROR);
1651 
1652 #if defined(sparc) || defined(__sparcv9)
1653 		if (allocate_got(ofl) == S_ERROR)
1654 			return (S_ERROR);
1655 #elif defined(i386) || defined(__amd64)
1656 /* nothing to do */
1657 #else
1658 #error Unknown architecture!
1659 #endif
1660 	}
1661 
1662 	return (1);
1663 }
1664 
1665 /*
1666  * Simple comparison routine to be used by qsort() for
1667  * the sorting of the output relocation list.
1668  *
1669  * The reloc_compare() routine results in a relocation
1670  * table which is located on:
1671  *
1672  *	file referenced (NEEDED NDX)
1673  *	referenced symbol
1674  *	relocation offset
1675  *
1676  * This provides the most efficient traversal of the relocation
1677  * table at run-time.
1678  */
1679 int
1680 reloc_compare(Reloc_list *i, Reloc_list *j)
1681 {
1682 
1683 	/*
1684 	 * first - sort on neededndx
1685 	 */
1686 	if (i->rl_key1 > j->rl_key1)
1687 		return (1);
1688 	if (i->rl_key1 < j->rl_key1)
1689 		return (-1);
1690 
1691 	/*
1692 	 * Then sort on symbol
1693 	 */
1694 	if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2)
1695 		return (1);
1696 	if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2)
1697 		return (-1);
1698 
1699 	/*
1700 	 * i->key2 == j->key2
1701 	 *
1702 	 * At this point we fall back to key2 (offsets) to
1703 	 * sort the output relocations.  Ideally this will
1704 	 * make for the most efficient processing of these
1705 	 * relocations at run-time.
1706 	 */
1707 	if (i->rl_key3 > j->rl_key3)
1708 		return (1);
1709 	if (i->rl_key3 < j->rl_key3)
1710 		return (-1);
1711 	return (0);
1712 }
1713 
1714 
1715 uintptr_t
1716 do_sorted_outrelocs(Ofl_desc *ofl)
1717 {
1718 	Rel_desc	*orsp;
1719 	Rel_cache	*rcp;
1720 	Listnode	*lnp;
1721 	Reloc_list	*sorted_list;
1722 	Word		index = 0;
1723 	int		debug = 0;
1724 	uintptr_t	error = 1;
1725 
1726 	if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) *
1727 	    ofl->ofl_reloccnt))) == NULL)
1728 		return (S_ERROR);
1729 
1730 	/*
1731 	 * All but the PLT output relocations are sorted in the output file
1732 	 * based upon their sym_desc.  By doing this multiple relocations
1733 	 * against the same symbol are grouped together, thus when the object
1734 	 * is later relocated by ld.so.1 it will take advantage of the symbol
1735 	 * cache that ld.so.1 has.  This can significantly reduce the runtime
1736 	 * relocation cost of a dynamic object.
1737 	 *
1738 	 * PLT relocations are not sorted because the order of the PLT
1739 	 * relocations is used by ld.so.1 to determine what symbol a PLT
1740 	 * relocation is against.
1741 	 */
1742 	for (LIST_TRAVERSE(&ofl->ofl_outrels, lnp, rcp)) {
1743 		/*LINTED*/
1744 		for (orsp = (Rel_desc *)(rcp + 1);
1745 		    orsp < rcp->rc_free; orsp++) {
1746 			if (debug == 0) {
1747 				DBG_CALL(Dbg_reloc_dooutrel(M_REL_SHT_TYPE));
1748 				debug = 1;
1749 			}
1750 
1751 			/*
1752 			 * If it's a PLT relocation we output it now in the
1753 			 * order that it was originally processed.
1754 			 */
1755 			if (orsp->rel_flags & FLG_REL_PLT) {
1756 				if (perform_outreloc(orsp, ofl) == S_ERROR)
1757 					error = S_ERROR;
1758 				continue;
1759 			}
1760 
1761 			if ((orsp->rel_rtype == M_R_RELATIVE) ||
1762 			    (orsp->rel_rtype == M_R_REGISTER)) {
1763 				sorted_list[index].rl_key1 = 0;
1764 				sorted_list[index].rl_key2 =
1765 				    /* LINTED */
1766 				    (Sym_desc *)(uintptr_t)orsp->rel_rtype;
1767 			} else {
1768 				sorted_list[index].rl_key1 =
1769 				    orsp->rel_sym->sd_file->ifl_neededndx;
1770 				sorted_list[index].rl_key2 =
1771 				    orsp->rel_sym;
1772 			}
1773 
1774 			if (orsp->rel_flags & FLG_REL_GOT)
1775 				sorted_list[index].rl_key3 =
1776 					calc_got_offset(orsp, ofl);
1777 			else {
1778 				if (orsp->rel_rtype == M_R_REGISTER)
1779 					sorted_list[index].rl_key3 = 0;
1780 				else {
1781 					sorted_list[index].rl_key3 =
1782 						orsp->rel_roffset +
1783 						(Xword)_elf_getxoff(orsp->
1784 						rel_isdesc->
1785 						is_indata) +
1786 						orsp->rel_isdesc->is_osdesc->
1787 						os_shdr->sh_addr;
1788 				}
1789 			}
1790 
1791 			sorted_list[index++].rl_rsp = orsp;
1792 		}
1793 	}
1794 
1795 	qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list),
1796 		(int (*)(const void *, const void *))reloc_compare);
1797 
1798 	/*
1799 	 * All output relocations have now been sorted, go through
1800 	 * and process each relocation.
1801 	 */
1802 	for (index = 0; index < ofl->ofl_reloccnt; index++) {
1803 		if (perform_outreloc(sorted_list[index].rl_rsp, ofl) ==
1804 		    S_ERROR)
1805 			error = S_ERROR;
1806 	}
1807 
1808 	return (error);
1809 }
1810 
1811 /*
1812  * Process relocations.  Finds every input relocation section for each output
1813  * section and invokes reloc_sec() to relocate that section.
1814  */
1815 uintptr_t
1816 reloc_process(Ofl_desc *ofl)
1817 {
1818 	Listnode	*lnp1;
1819 	Sg_desc		*sgp;
1820 	Word		ndx = 0, flags = ofl->ofl_flags;
1821 	Shdr		*shdr;
1822 
1823 	/*
1824 	 * Determine the index of the symbol table that will be referenced by
1825 	 * the relocation entries.
1826 	 */
1827 	if ((flags & (FLG_OF_DYNAMIC|FLG_OF_RELOBJ)) == FLG_OF_DYNAMIC)
1828 		/* LINTED */
1829 		ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
1830 	else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
1831 		/* LINTED */
1832 		ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
1833 
1834 	/*
1835 	 * Re-initialize counters. These are used to provide relocation
1836 	 * offsets within the output buffers.
1837 	 */
1838 	ofl->ofl_relocpltsz = 0;
1839 	ofl->ofl_relocgotsz = 0;
1840 	ofl->ofl_relocbsssz = 0;
1841 
1842 	/*
1843 	 * Now that the output file is created and symbol update has occurred,
1844 	 * process the relocations collected in process_reloc().
1845 	 */
1846 	if (do_sorted_outrelocs(ofl) == S_ERROR)
1847 		return (S_ERROR);
1848 
1849 	if (do_activerelocs(ofl) == S_ERROR)
1850 		return (S_ERROR);
1851 
1852 	if ((ofl->ofl_flags1 & FLG_OF1_RELCNT) == 0) {
1853 		/*
1854 		 * Process the relocation sections:
1855 		 *
1856 		 *  o	for each relocation section generated for the output
1857 		 *	image update its shdr information to reflect the
1858 		 *	symbol table it needs (sh_link) and the section to
1859 		 *	which the relocation must be applied (sh_info).
1860 		 */
1861 		for (LIST_TRAVERSE(&ofl->ofl_segs, lnp1, sgp)) {
1862 			Listnode *	lnp2;
1863 			Os_desc *	osp;
1864 
1865 			for (LIST_TRAVERSE(&(sgp->sg_osdescs), lnp2, osp)) {
1866 				if (osp->os_relosdesc == 0)
1867 					continue;
1868 
1869 				shdr = osp->os_relosdesc->os_shdr;
1870 				shdr->sh_link = ndx;
1871 				/* LINTED */
1872 				shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
1873 			}
1874 		}
1875 
1876 		/*
1877 		 * Since the .rel[a] section is not tied to any specific
1878 		 * section, we'd of not found it above.
1879 		 */
1880 		if (ofl->ofl_osrel) {
1881 			shdr = ofl->ofl_osrel->os_shdr;
1882 			shdr->sh_link = ndx;
1883 			shdr->sh_info = 0;
1884 		}
1885 	} else {
1886 		/*
1887 		 * We only have two relocation sections here, (PLT's,
1888 		 * coalesced) so just hit them directly instead of stepping
1889 		 * over the output sections.
1890 		 */
1891 		if (ofl->ofl_osrelhead) {
1892 			shdr = ofl->ofl_osrelhead->os_shdr;
1893 			shdr->sh_link = ndx;
1894 			shdr->sh_info = 0;
1895 		}
1896 		if (ofl->ofl_osplt && ofl->ofl_osplt->os_relosdesc) {
1897 			shdr = ofl->ofl_osplt->os_relosdesc->os_shdr;
1898 			shdr->sh_link = ndx;
1899 			/* LINTED */
1900 			shdr->sh_info =
1901 			    (Word)elf_ndxscn(ofl->ofl_osplt->os_scn);
1902 		}
1903 	}
1904 
1905 	/*
1906 	 * If the -z text option was given, and we have output relocations
1907 	 * against a non-writable, allocatable section, issue a diagnostic and
1908 	 * return (the actual entries that caused this error would have been
1909 	 * output during the relocating section phase).
1910 	 */
1911 	if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) ==
1912 	    (FLG_OF_PURETXT | FLG_OF_TEXTREL)) {
1913 		eprintf(ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
1914 		return (S_ERROR);
1915 	}
1916 
1917 	/*
1918 	 * Finally, initialize the first got entry with the address of the
1919 	 * .dynamic section (_DYNAMIC).
1920 	 */
1921 	if (flags & FLG_OF_DYNAMIC) {
1922 		if (fillin_gotplt1(ofl) == S_ERROR)
1923 			return (S_ERROR);
1924 	}
1925 
1926 	return (1);
1927 }
1928 
1929 /*
1930  * If the -z text option was given, and we have output relocations against a
1931  * non-writable, allocatable section, issue a diagnostic. Print offending
1932  * symbols in tabular form similar to the way undefined symbols are presented.
1933  * Called from reloc_count().  The actual fatal error condition is triggered on
1934  * in reloc_process() above.
1935  *
1936  * Note.  For historic reasons -ztext is not a default option (however all OS
1937  * shared object builds use this option).  It can be argued that this option
1938  * should also be default when generating an a.out (see 1163979).  However, if
1939  * an a.out contains text relocations it is either because the user is creating
1940  * something pretty weird (they've used the -b or -znodefs options), or because
1941  * the library against which they're building wasn't constructed correctly (ie.
1942  * a function has a NOTYPE type, in which case the a.out won't generate an
1943  * associated plt).  In the latter case the builder of the a.out can't do
1944  * anything to fix the error - thus we've chosen not to give the user an error,
1945  * or warning, for this case.
1946  */
1947 
1948 void
1949 reloc_remain_title(int warning)
1950 {
1951 	const char	*str1;
1952 
1953 	if (warning)
1954 		str1 = MSG_INTL(MSG_REL_RMN_ITM_13);
1955 	else
1956 		str1 = MSG_INTL(MSG_REL_RMN_ITM_11);
1957 
1958 	eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1),
1959 		str1,
1960 		MSG_INTL(MSG_REL_RMN_ITM_31),
1961 		MSG_INTL(MSG_REL_RMN_ITM_12),
1962 		MSG_INTL(MSG_REL_RMN_ITM_2),
1963 		MSG_INTL(MSG_REL_RMN_ITM_32));
1964 
1965 }
1966 
1967 void
1968 reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl)
1969 {
1970 	static Boolean	reloc_title = TRUE;
1971 
1972 	/*
1973 	 * -ztextoff
1974 	 */
1975 	if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)
1976 		return;
1977 
1978 	/*
1979 	 * Only give relocation errors against loadable read-only segments.
1980 	 */
1981 	if ((orsp->rel_rtype == M_R_REGISTER) || (!osp) ||
1982 	    (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) ||
1983 	    (osp->os_sgdesc->sg_phdr.p_flags & PF_W))
1984 		return;
1985 
1986 	/*
1987 	 * If we are in -ztextwarn mode, it's a silent error if a relocation is
1988 	 * due to a 'WEAK REFERENCE'.  This is because if the symbol is not
1989 	 * provided at run-time we will not perform a text-relocation.
1990 	 */
1991 	if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) &&
1992 	    (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) &&
1993 	    (orsp->rel_sym->sd_shndx == SHN_UNDEF))
1994 		return;
1995 
1996 	if (reloc_title) {
1997 		/*
1998 		 * If building with '-ztext' then emit a fatal error.  If
1999 		 * building a executable then only emit a 'warning'.
2000 		 */
2001 		if (ofl->ofl_flags & FLG_OF_PURETXT)
2002 			reloc_remain_title(0);
2003 		else
2004 			reloc_remain_title(1);
2005 		reloc_title = FALSE;
2006 	}
2007 
2008 	eprintf(ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2), demangle(orsp->rel_sname),
2009 	    EC_OFF(orsp->rel_roffset), orsp->rel_isdesc->is_file->ifl_name);
2010 }
2011 
2012 /*
2013  * The following functions are called from
2014  * machine functions defined in {sparc,i386,sparcv9}/machrel.c
2015  */
2016 
2017 /*
2018  * Move Section related function
2019  */
2020 static uintptr_t
2021 newroffset_for_move(Sym_desc *symd,
2022 	Move *mventry, Xword offset1, Xword *offset2)
2023 {
2024 	Psym_info	*psym = symd->sd_psyminfo;
2025 	Mv_itm		*itm;
2026 	Listnode	*lnp1;
2027 	int 		found = 0;
2028 
2029 	/*
2030 	 * Search for matching move entry
2031 	 */
2032 	found = 0;
2033 	for (LIST_TRAVERSE(&psym->psym_mvs, lnp1, itm)) {
2034 		if (itm->mv_ientry == mventry) {
2035 			found = 1;
2036 			break;
2037 		}
2038 	}
2039 	if (found == 0) {
2040 		/*
2041 		 * This should never happen.
2042 		 */
2043 		return (S_ERROR);
2044 	}
2045 
2046 	/*
2047 	 * Update r_offset
2048 	 */
2049 	*offset2 = (Xword)((itm->mv_oidx - 1)*sizeof (Move) +
2050 		offset1 % sizeof (Move));
2051 	return (1);
2052 }
2053 
2054 void
2055 adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp)
2056 {
2057 	Move		*move = arsp->rel_move->mvd_move;
2058 	Sym_desc	*psdp = arsp->rel_move->mvd_sym;
2059 	Xword		newoffset;
2060 
2061 	if (arsp->rel_flags & FLG_REL_MOVETAB) {
2062 		/*
2063 		 * We are relocating the move table itself.
2064 		 */
2065 		(void) newroffset_for_move(psdp, move, arsp->rel_roffset,
2066 		    &newoffset);
2067 		DBG_CALL(Dbg_move_adjmovereloc(arsp->rel_roffset, newoffset,
2068 		    psdp->sd_name));
2069 		arsp->rel_roffset = newoffset;
2070 	} else {
2071 		/*
2072 		 * We are expanding the partial symbol.  So we are generating
2073 		 * the relocation entry relocating the expanded partial symbol.
2074 		 */
2075 		arsp->rel_roffset +=
2076 		    psdp->sd_sym->st_value -
2077 		    ofl->ofl_issunwdata1->is_osdesc->os_shdr->sh_addr;
2078 		DBG_CALL(Dbg_move_adjexpandreloc(arsp->rel_roffset,
2079 		    psdp->sd_name));
2080 	}
2081 }
2082 
2083 /*
2084  * Partially Initialized Symbol Handling routines
2085  * For sparc architecture, the second argument is reld->rel_raddend.
2086  * For i386  acrchitecure, the second argument is the value stored
2087  *	at the relocation target address.
2088  */
2089 Sym_desc *
2090 am_I_partial(Rel_desc *reld, Xword val)
2091 {
2092 	Ifl_desc *	ifile = reld->rel_sym->sd_isc->is_file;
2093 	int 		nlocs = ifile->ifl_locscnt, i;
2094 
2095 	for (i = 1; i < nlocs; i++) {
2096 		Sym *		osym;
2097 		Sym_desc *	symd = ifile->ifl_oldndx[i];
2098 
2099 		if ((osym = symd->sd_osym) == 0)
2100 			continue;
2101 		if ((symd->sd_flags & FLG_SY_PAREXPN) == 0)
2102 			continue;
2103 		if ((osym->st_value <= val) &&
2104 		    (osym->st_value + osym->st_size  > val))
2105 			return (symd);
2106 	}
2107 	return ((Sym_desc *) 0);
2108 }
2109 
2110 /*
2111  * Because of the combinations of 32-bit lib providing 64-bit support, and
2112  * visa-versa, the use of krtld's dorelocs can result in differing message
2113  * requirements that make msg.c/msg.h creation and chkmsg "interesting".
2114  * Thus the actual message files contain a couple of entries to satisfy
2115  * each architectures build.  Here we add dummy calls to quieten chkmsg.
2116  *
2117  * chkmsg: MSG_INTL(MSG_REL_NOFIT)
2118  * chkmsg: MSG_INTL(MSG_REL_NONALIGN)
2119  */
2120