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