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