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