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