xref: /illumos-gate/usr/src/cmd/sgs/libld/common/update.c (revision a196c3ff)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  *	Copyright (c) 1988 AT&T
24  *	  All Rights Reserved
25  *
26  * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
27  */
28 
29 /*
30  * Update the new output file image, perform virtual address, offset and
31  * displacement calculations on the program headers and sections headers,
32  * and generate any new output section information.
33  */
34 
35 #define	ELF_TARGET_AMD64
36 
37 #include	<stdio.h>
38 #include	<string.h>
39 #include	<unistd.h>
40 #include	<debug.h>
41 #include	"msg.h"
42 #include	"_libld.h"
43 
44 /*
45  * Comparison routine used by qsort() for sorting of the global symbol list
46  * based off of the hashbuckets the symbol will eventually be deposited in.
47  */
48 static int
sym_hash_compare(Sym_s_list * s1,Sym_s_list * s2)49 sym_hash_compare(Sym_s_list * s1, Sym_s_list * s2)
50 {
51 	return (s1->sl_hval - s2->sl_hval);
52 }
53 
54 /*
55  * Comparison routine used by qsort() for sorting of dyn[sym|tls]sort section
56  * indices based on the address of the symbols they reference. The
57  * use of the global dynsort_compare_syms variable is needed because
58  * we need to examine the symbols the indices reference. It is safe, because
59  * the linker is single threaded.
60  */
61 static Sym *dynsort_compare_syms;
62 
63 static int
dynsort_compare(const void * idx1,const void * idx2)64 dynsort_compare(const void *idx1, const void *idx2)
65 {
66 	Sym *s1 = dynsort_compare_syms + *((const Word *) idx1);
67 	Sym *s2 = dynsort_compare_syms + *((const Word *) idx2);
68 
69 	/*
70 	 * Note: the logical computation for this is
71 	 *	(st_value1 - st_value2)
72 	 * However, that is only correct if the address type is smaller
73 	 * than a pointer. Writing it this way makes it immune to the
74 	 * class (32 or 64-bit) of the linker.
75 	 */
76 	return ((s1->st_value < s2->st_value) ? -1 :
77 	    (s1->st_value > s2->st_value));
78 }
79 
80 /*
81  * Scan the sorted symbols, and issue warnings if there are any duplicate
82  * values in the list. We only do this if -zverbose is set, or we are
83  * running with LD_DEBUG defined
84  *
85  * entry:
86  *	ofl - Output file descriptor
87  *	ldynsym - Pointer to start of .SUNW_ldynsym section that the
88  *		sort section indexes reference.
89  *	symsort - Pointer to start of .SUNW_dynsymsort or .SUNW_dyntlssort
90  *		section.
91  *	n - # of indices in symsort array
92  *	secname - Name of the symsort section.
93  *
94  * exit:
95  *	If the symsort section contains indexes to more than one
96  *	symbol with the same address value, a warning is issued.
97  */
98 static void
dynsort_dupwarn(Ofl_desc * ofl,Sym * ldynsym,const char * str,Word * symsort,Word n,const char * secname)99 dynsort_dupwarn(Ofl_desc *ofl, Sym *ldynsym, const char *str,
100     Word *symsort, Word n, const char *secname)
101 {
102 	int zverbose = (ofl->ofl_flags & FLG_OF_VERBOSE) != 0;
103 	Word ndx, cmp_ndx;
104 	Addr addr, cmp_addr;
105 
106 	/* Nothing to do if -zverbose or LD_DEBUG are not active */
107 	if (!(zverbose || DBG_ENABLED))
108 		return;
109 
110 	cmp_ndx = 0;
111 	cmp_addr = ldynsym[symsort[cmp_ndx]].st_value;
112 	for (ndx = 1; ndx < n; ndx++) {
113 		addr = ldynsym[symsort[ndx]].st_value;
114 		if (cmp_addr == addr) {
115 			if (zverbose)
116 				ld_eprintf(ofl, ERR_WARNING,
117 				    MSG_INTL(MSG_SYM_DUPSORTADDR), secname,
118 				    str + ldynsym[symsort[cmp_ndx]].st_name,
119 				    str + ldynsym[symsort[ndx]].st_name,
120 				    EC_ADDR(addr));
121 			DBG_CALL(Dbg_syms_dup_sort_addr(ofl->ofl_lml, secname,
122 			    str + ldynsym[symsort[cmp_ndx]].st_name,
123 			    str + ldynsym[symsort[ndx]].st_name,
124 			    EC_ADDR(addr)));
125 		} else {	/* Not a dup. Move reference up */
126 			cmp_ndx = ndx;
127 			cmp_addr = addr;
128 		}
129 	}
130 }
131 
132 static inline Boolean
ass_enabled(Ass_desc * ma,uint_t ass)133 ass_enabled(Ass_desc *ma, uint_t ass)
134 {
135 	return ((ma->ass_enabled & ass) != 0);
136 }
137 
138 /*
139  * Build and update any output symbol tables.  Here we work on all the symbol
140  * tables at once to reduce the duplication of symbol and string manipulation.
141  * Symbols and their associated strings are copied from the read-only input
142  * file images to the output image and their values and index's updated in the
143  * output image.
144  */
145 static Addr
update_osym(Ofl_desc * ofl)146 update_osym(Ofl_desc *ofl)
147 {
148 	/*
149 	 * There are several places in this function where we wish
150 	 * to insert a symbol index to the combined .SUNW_ldynsym/.dynsym
151 	 * symbol table into one of the two sort sections (.SUNW_dynsymsort
152 	 * or .SUNW_dyntlssort), if that symbol has the right attributes.
153 	 * This macro is used to generate the necessary code from a single
154 	 * specification.
155 	 *
156 	 * entry:
157 	 *	_sdp, _sym, _type - As per DYNSORT_COUNT. See _libld.h
158 	 *	_sym_ndx - Index that _sym will have in the combined
159 	 *		.SUNW_ldynsym/.dynsym symbol table.
160 	 */
161 #define	ADD_TO_DYNSORT(_sdp, _sym, _type, _sym_ndx) \
162 	{ \
163 		Word *_dynsort_arr, *_dynsort_ndx; \
164 		\
165 		if (dynsymsort_symtype[_type]) { \
166 			_dynsort_arr = dynsymsort; \
167 			_dynsort_ndx = &dynsymsort_ndx; \
168 		} else if (_type == STT_TLS) { \
169 			_dynsort_arr = dyntlssort; \
170 			_dynsort_ndx = &dyntlssort_ndx; \
171 		} else { \
172 			_dynsort_arr = NULL; \
173 		} \
174 		if ((_dynsort_arr != NULL) && DYNSORT_TEST_ATTR(_sdp, _sym)) \
175 		    _dynsort_arr[(*_dynsort_ndx)++] = _sym_ndx; \
176 	}
177 
178 	Sym_desc	*sdp;
179 	Sym_avlnode	*sav;
180 	Sg_desc		*sgp, *tsgp = NULL, *dsgp = NULL, *esgp = NULL;
181 	Os_desc		*osp, *iosp = NULL, *fosp = NULL;
182 	Is_desc		*isc;
183 	Ifl_desc	*ifl;
184 	Word		bssndx, etext_ndx, edata_ndx = 0, end_ndx, start_ndx;
185 	Word		end_abs = 0, etext_abs = 0, edata_abs;
186 	Word		tlsbssndx = 0, parexpnndx;
187 #if	defined(_ELF64)
188 	Word		lbssndx = 0;
189 	Addr		lbssaddr = 0;
190 #endif
191 	Addr		bssaddr, etext = 0, edata = 0, end = 0, start = 0;
192 	Addr		tlsbssaddr = 0;
193 	Addr		parexpnbase, parexpnaddr;
194 	int		start_set = 0;
195 	Sym		_sym = {0}, *sym, *symtab = NULL;
196 	Sym		*dynsym = NULL, *ldynsym = NULL;
197 	Word		symtab_ndx = 0;		/* index into .symtab */
198 	Word		symtab_gbl_bndx;	/* .symtab ndx 1st global */
199 	Word		ldynsym_ndx = 0;	/* index into .SUNW_ldynsym */
200 	Word		dynsym_ndx = 0;		/* index into .dynsym */
201 	Word		scopesym_ndx = 0;	/* index into scoped symbols */
202 	Word		scopesym_bndx = 0;	/* .symtab ndx 1st scoped sym */
203 	Word		ldynscopesym_ndx = 0;	/* index to ldynsym scoped */
204 						/*	symbols */
205 	Word		*dynsymsort = NULL;	/* SUNW_dynsymsort index */
206 						/*	vector */
207 	Word		*dyntlssort = NULL;	/* SUNW_dyntlssort index */
208 						/*	vector */
209 	Word		dynsymsort_ndx;		/* index dynsymsort array */
210 	Word		dyntlssort_ndx;		/* index dyntlssort array */
211 	Word		*symndx;		/* symbol index (for */
212 						/*	relocation use) */
213 	Word		*symshndx = NULL;	/* .symtab_shndx table */
214 	Word		*dynshndx = NULL;	/* .dynsym_shndx table */
215 	Word		*ldynshndx = NULL;	/* .SUNW_ldynsym_shndx table */
216 	Word		ldynsym_cnt = 0;	/* number of items in */
217 						/*	.SUNW_ldynsym */
218 	Str_tbl		*shstrtab;
219 	Str_tbl		*strtab;
220 	Str_tbl		*dynstr;
221 	Word		*hashtab;	/* hash table pointer */
222 	Word		*hashbkt;	/* hash table bucket pointer */
223 	Word		*hashchain;	/* hash table chain pointer */
224 	Wk_desc		*wkp;
225 	Alist		*weak = NULL;
226 	ofl_flag_t	flags = ofl->ofl_flags;
227 	Versym		*versym;
228 	Gottable	*gottable;	/* used for display got debugging */
229 					/*	information */
230 	Syminfo		*syminfo;
231 	Sym_s_list	*sorted_syms;	/* table to hold sorted symbols */
232 	Word		ssndx;		/* global index into sorted_syms */
233 	Word		scndx;		/* scoped index into sorted_syms */
234 	size_t		stoff;		/* string offset */
235 	Aliste		idx1;
236 
237 	/*
238 	 * Initialize pointers to the symbol table entries and the symbol
239 	 * table strings.  Skip the first symbol entry and the first string
240 	 * table byte.  Note that if we are not generating any output symbol
241 	 * tables we must still generate and update internal copies so
242 	 * that the relocation phase has the correct information.
243 	 */
244 	if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ) ||
245 	    ((flags & FLG_OF_STATIC) && ofl->ofl_osversym)) {
246 		symtab = (Sym *)ofl->ofl_ossymtab->os_outdata->d_buf;
247 		symtab[symtab_ndx++] = _sym;
248 		if (ofl->ofl_ossymshndx)
249 			symshndx =
250 			    (Word *)ofl->ofl_ossymshndx->os_outdata->d_buf;
251 	}
252 	if (OFL_ALLOW_DYNSYM(ofl)) {
253 		dynsym = (Sym *)ofl->ofl_osdynsym->os_outdata->d_buf;
254 		dynsym[dynsym_ndx++] = _sym;
255 		/*
256 		 * If we are also constructing a .SUNW_ldynsym section
257 		 * to contain local function symbols, then set it up too.
258 		 */
259 		if (ofl->ofl_osldynsym) {
260 			ldynsym = (Sym *)ofl->ofl_osldynsym->os_outdata->d_buf;
261 			ldynsym[ldynsym_ndx++] = _sym;
262 			ldynsym_cnt = 1 + ofl->ofl_dynlocscnt +
263 			    ofl->ofl_dynscopecnt;
264 
265 			/*
266 			 * If there is a SUNW_ldynsym, then there may also
267 			 * be a .SUNW_dynsymsort and/or .SUNW_dyntlssort
268 			 * sections, used to collect indices of function
269 			 * and data symbols sorted by address order.
270 			 */
271 			if (ofl->ofl_osdynsymsort) {	/* .SUNW_dynsymsort */
272 				dynsymsort = (Word *)
273 				    ofl->ofl_osdynsymsort->os_outdata->d_buf;
274 				dynsymsort_ndx = 0;
275 			}
276 			if (ofl->ofl_osdyntlssort) {	/* .SUNW_dyntlssort */
277 				dyntlssort = (Word *)
278 				    ofl->ofl_osdyntlssort->os_outdata->d_buf;
279 				dyntlssort_ndx = 0;
280 			}
281 		}
282 
283 		/*
284 		 * Initialize the hash table.
285 		 */
286 		hashtab = (Word *)(ofl->ofl_oshash->os_outdata->d_buf);
287 		hashbkt = &hashtab[2];
288 		hashchain = &hashtab[2 + ofl->ofl_hashbkts];
289 		hashtab[0] = ofl->ofl_hashbkts;
290 		hashtab[1] = DYNSYM_ALL_CNT(ofl);
291 		if (ofl->ofl_osdynshndx)
292 			dynshndx =
293 			    (Word *)ofl->ofl_osdynshndx->os_outdata->d_buf;
294 		if (ofl->ofl_osldynshndx)
295 			ldynshndx =
296 			    (Word *)ofl->ofl_osldynshndx->os_outdata->d_buf;
297 	}
298 
299 	/*
300 	 * symndx is the symbol index to be used for relocation processing.  It
301 	 * points to the relevant symtab's (.dynsym or .symtab) symbol ndx.
302 	 */
303 	if (dynsym)
304 		symndx = &dynsym_ndx;
305 	else
306 		symndx = &symtab_ndx;
307 
308 	/*
309 	 * If we have version definitions initialize the version symbol index
310 	 * table.  There is one entry for each symbol which contains the symbols
311 	 * version index.
312 	 */
313 	if (!(flags & FLG_OF_NOVERSEC) &&
314 	    (flags & (FLG_OF_VERNEED | FLG_OF_VERDEF))) {
315 		versym = (Versym *)ofl->ofl_osversym->os_outdata->d_buf;
316 		versym[0] = 0;
317 	} else
318 		versym = NULL;
319 
320 	/*
321 	 * If syminfo section exists be prepared to fill it in.
322 	 */
323 	if (ofl->ofl_ossyminfo) {
324 		syminfo = ofl->ofl_ossyminfo->os_outdata->d_buf;
325 		syminfo[0].si_flags = SYMINFO_CURRENT;
326 	} else
327 		syminfo = NULL;
328 
329 	/*
330 	 * Setup our string tables.
331 	 */
332 	shstrtab = ofl->ofl_shdrsttab;
333 	strtab = ofl->ofl_strtab;
334 	dynstr = ofl->ofl_dynstrtab;
335 
336 	DBG_CALL(Dbg_syms_sec_title(ofl->ofl_lml));
337 
338 	/*
339 	 * Put output file name to the first .symtab and .SUNW_ldynsym symbol.
340 	 */
341 	if (symtab) {
342 		(void) st_setstring(strtab, ofl->ofl_name, &stoff);
343 		sym = &symtab[symtab_ndx++];
344 		/* LINTED */
345 		sym->st_name = stoff;
346 		sym->st_value = 0;
347 		sym->st_size = 0;
348 		sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);
349 		sym->st_other = 0;
350 		sym->st_shndx = SHN_ABS;
351 
352 		if (versym && !dynsym)
353 			versym[1] = 0;
354 	}
355 	if (ldynsym) {
356 		(void) st_setstring(dynstr, ofl->ofl_name, &stoff);
357 		sym = &ldynsym[ldynsym_ndx];
358 		/* LINTED */
359 		sym->st_name = stoff;
360 		sym->st_value = 0;
361 		sym->st_size = 0;
362 		sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);
363 		sym->st_other = 0;
364 		sym->st_shndx = SHN_ABS;
365 
366 		/* Scoped symbols get filled in global loop below */
367 		ldynscopesym_ndx = ldynsym_ndx + 1;
368 		ldynsym_ndx += ofl->ofl_dynscopecnt;
369 	}
370 
371 	/*
372 	 * If we are to display GOT summary information, then allocate
373 	 * the buffer to 'cache' the GOT symbols into now.
374 	 */
375 	if (DBG_ENABLED) {
376 		if ((ofl->ofl_gottable = gottable =
377 		    libld_calloc(ofl->ofl_gotcnt, sizeof (Gottable))) == NULL)
378 			return ((Addr)S_ERROR);
379 	}
380 
381 	/*
382 	 * Traverse the program headers.  Determine the last executable segment
383 	 * and the last data segment so that we can update etext and edata. If
384 	 * we have empty segments (reservations) record them for setting _end.
385 	 */
386 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
387 		Phdr	*phd = &(sgp->sg_phdr);
388 		Os_desc	*osp;
389 		Aliste	idx2;
390 
391 		if (phd->p_type == PT_LOAD) {
392 			if (aplist_nitems(sgp->sg_osdescs) != 0) {
393 				Word	_flags = phd->p_flags & (PF_W | PF_R);
394 
395 				if (_flags == PF_R)
396 					tsgp = sgp;
397 				else if (_flags == (PF_W | PF_R))
398 					dsgp = sgp;
399 			} else if (sgp->sg_flags & FLG_SG_EMPTY)
400 				esgp = sgp;
401 		}
402 
403 		/*
404 		 * Generate a section symbol for each output section.
405 		 */
406 		for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
407 			Word	sectndx;
408 
409 			sym = &_sym;
410 			sym->st_value = osp->os_shdr->sh_addr;
411 			sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION);
412 			/* LINTED */
413 			sectndx = elf_ndxscn(osp->os_scn);
414 
415 			if (symtab) {
416 				if (sectndx >= SHN_LORESERVE) {
417 					symshndx[symtab_ndx] = sectndx;
418 					sym->st_shndx = SHN_XINDEX;
419 				} else {
420 					/* LINTED */
421 					sym->st_shndx = (Half)sectndx;
422 				}
423 				symtab[symtab_ndx++] = *sym;
424 			}
425 
426 			if (dynsym && (osp->os_flags & FLG_OS_OUTREL))
427 				dynsym[dynsym_ndx++] = *sym;
428 
429 			if ((dynsym == NULL) ||
430 			    (osp->os_flags & FLG_OS_OUTREL)) {
431 				if (versym)
432 					versym[*symndx - 1] = 0;
433 				osp->os_identndx = *symndx - 1;
434 				DBG_CALL(Dbg_syms_sec_entry(ofl->ofl_lml,
435 				    osp->os_identndx, sgp, osp));
436 			}
437 
438 			/*
439 			 * Generate the .shstrtab for this section.
440 			 */
441 			(void) st_setstring(shstrtab, osp->os_name, &stoff);
442 			osp->os_shdr->sh_name = (Word)stoff;
443 
444 			/*
445 			 * Find the section index for our special symbols.
446 			 */
447 			if (sgp == tsgp) {
448 				/* LINTED */
449 				etext_ndx = elf_ndxscn(osp->os_scn);
450 			} else if (dsgp == sgp) {
451 				if (osp->os_shdr->sh_type != SHT_NOBITS) {
452 					/* LINTED */
453 					edata_ndx = elf_ndxscn(osp->os_scn);
454 				}
455 			}
456 
457 			if (start_set == 0) {
458 				start = sgp->sg_phdr.p_vaddr;
459 				/* LINTED */
460 				start_ndx = elf_ndxscn(osp->os_scn);
461 				start_set++;
462 			}
463 
464 			/*
465 			 * While we're here, determine whether a .init or .fini
466 			 * section exist.
467 			 */
468 			if ((iosp == NULL) && (strcmp(osp->os_name,
469 			    MSG_ORIG(MSG_SCN_INIT)) == 0))
470 				iosp = osp;
471 			if ((fosp == NULL) && (strcmp(osp->os_name,
472 			    MSG_ORIG(MSG_SCN_FINI)) == 0))
473 				fosp = osp;
474 		}
475 	}
476 
477 	/*
478 	 * Add local register symbols to the .dynsym.  These are required as
479 	 * DT_REGISTER .dynamic entries must have a symbol to reference.
480 	 */
481 	if (ofl->ofl_regsyms && dynsym) {
482 		int	ndx;
483 
484 		for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) {
485 			Sym_desc	*rsdp;
486 
487 			if ((rsdp = ofl->ofl_regsyms[ndx]) == NULL)
488 				continue;
489 
490 			if (!SYM_IS_HIDDEN(rsdp) &&
491 			    (ELF_ST_BIND(rsdp->sd_sym->st_info) != STB_LOCAL))
492 				continue;
493 
494 			dynsym[dynsym_ndx] = *(rsdp->sd_sym);
495 			rsdp->sd_symndx = *symndx;
496 
497 			if (dynsym[dynsym_ndx].st_name) {
498 				(void) st_setstring(dynstr, rsdp->sd_name,
499 				    &stoff);
500 				dynsym[dynsym_ndx].st_name = stoff;
501 			}
502 			dynsym_ndx++;
503 		}
504 	}
505 
506 	/*
507 	 * Having traversed all the output segments, warn the user if the
508 	 * traditional text or data segments don't exist.  Otherwise from these
509 	 * segments establish the values for `etext', `edata', `end', `END',
510 	 * and `START'.
511 	 */
512 	if (!(flags & FLG_OF_RELOBJ)) {
513 		Sg_desc	*sgp;
514 
515 		if (tsgp)
516 			etext = tsgp->sg_phdr.p_vaddr + tsgp->sg_phdr.p_filesz;
517 		else {
518 			etext = (Addr)0;
519 			etext_ndx = SHN_ABS;
520 			etext_abs = 1;
521 			if (flags & FLG_OF_VERBOSE)
522 				ld_eprintf(ofl, ERR_WARNING,
523 				    MSG_INTL(MSG_UPD_NOREADSEG));
524 		}
525 		if (dsgp) {
526 			edata = dsgp->sg_phdr.p_vaddr + dsgp->sg_phdr.p_filesz;
527 		} else {
528 			edata = (Addr)0;
529 			edata_ndx = SHN_ABS;
530 			edata_abs = 1;
531 			if (flags & FLG_OF_VERBOSE)
532 				ld_eprintf(ofl, ERR_WARNING,
533 				    MSG_INTL(MSG_UPD_NORDWRSEG));
534 		}
535 
536 		if (dsgp == NULL) {
537 			if (tsgp)
538 				sgp = tsgp;
539 			else
540 				sgp = 0;
541 		} else if (tsgp == NULL)
542 			sgp = dsgp;
543 		else if (dsgp->sg_phdr.p_vaddr > tsgp->sg_phdr.p_vaddr)
544 			sgp = dsgp;
545 		else if (dsgp->sg_phdr.p_vaddr < tsgp->sg_phdr.p_vaddr)
546 			sgp = tsgp;
547 		else {
548 			/*
549 			 * One of the segments must be of zero size.
550 			 */
551 			if (tsgp->sg_phdr.p_memsz)
552 				sgp = tsgp;
553 			else
554 				sgp = dsgp;
555 		}
556 
557 		if (esgp && (esgp->sg_phdr.p_vaddr > sgp->sg_phdr.p_vaddr))
558 			sgp = esgp;
559 
560 		if (sgp) {
561 			end = sgp->sg_phdr.p_vaddr + sgp->sg_phdr.p_memsz;
562 
563 			/*
564 			 * If the last loadable segment is a read-only segment,
565 			 * then the application which uses the symbol _end to
566 			 * find the beginning of writable heap area may cause
567 			 * segmentation violation. We adjust the value of the
568 			 * _end to skip to the next page boundary.
569 			 *
570 			 * 6401812 System interface which returs beginning
571 			 *	   heap would be nice.
572 			 * When the above RFE is implemented, the changes below
573 			 * could be changed in a better way.
574 			 */
575 			if ((sgp->sg_phdr.p_flags & PF_W) == 0)
576 				end = (Addr)S_ROUND(end, sysconf(_SC_PAGESIZE));
577 
578 			/*
579 			 * If we're dealing with a memory reservation there are
580 			 * no sections to establish an index for _end, so assign
581 			 * it as an absolute.
582 			 */
583 			if (aplist_nitems(sgp->sg_osdescs) != 0) {
584 				/*
585 				 * Determine the last section for this segment.
586 				 */
587 				Os_desc	*osp = sgp->sg_osdescs->apl_data
588 				    [sgp->sg_osdescs->apl_nitems - 1];
589 
590 				/* LINTED */
591 				end_ndx = elf_ndxscn(osp->os_scn);
592 			} else {
593 				end_ndx = SHN_ABS;
594 				end_abs = 1;
595 			}
596 		} else {
597 			end = (Addr) 0;
598 			end_ndx = SHN_ABS;
599 			end_abs = 1;
600 			ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_UPD_NOSEG));
601 		}
602 	}
603 
604 	/*
605 	 * Initialize the scoped symbol table entry point.  This is for all
606 	 * the global symbols that have been scoped to locals and will be
607 	 * filled in during global symbol processing so that we don't have
608 	 * to traverse the globals symbol hash array more than once.
609 	 */
610 	if (symtab) {
611 		scopesym_bndx = symtab_ndx;
612 		scopesym_ndx = scopesym_bndx;
613 		symtab_ndx += ofl->ofl_scopecnt;
614 	}
615 
616 	/*
617 	 * If expanding partially expanded symbols under '-z nopartial',
618 	 * prepare to do that.
619 	 */
620 	if (ofl->ofl_isparexpn) {
621 		osp = ofl->ofl_isparexpn->is_osdesc;
622 		parexpnbase = parexpnaddr = (Addr)(osp->os_shdr->sh_addr +
623 		    ofl->ofl_isparexpn->is_indata->d_off);
624 		/* LINTED */
625 		parexpnndx = elf_ndxscn(osp->os_scn);
626 		ofl->ofl_parexpnndx = osp->os_identndx;
627 	}
628 
629 	/*
630 	 * If we are generating a .symtab collect all the local symbols,
631 	 * assigning a new virtual address or displacement (value).
632 	 */
633 	for (APLIST_TRAVERSE(ofl->ofl_objs, idx1, ifl)) {
634 		Xword		lndx, local = ifl->ifl_locscnt;
635 		Cap_desc	*cdp = ifl->ifl_caps;
636 
637 		for (lndx = 1; lndx < local; lndx++) {
638 			Gotndx		*gnp;
639 			uchar_t		type;
640 			Word		*_symshndx;
641 			int		enter_in_symtab, enter_in_ldynsym;
642 			int		update_done;
643 
644 			sdp = ifl->ifl_oldndx[lndx];
645 			sym = sdp->sd_sym;
646 
647 			/*
648 			 * Assign a got offset if necessary.
649 			 */
650 			if ((ld_targ.t_mr.mr_assign_got != NULL) &&
651 			    (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR)
652 				return ((Addr)S_ERROR);
653 
654 			if (DBG_ENABLED) {
655 				Aliste	idx2;
656 
657 				for (ALIST_TRAVERSE(sdp->sd_GOTndxs,
658 				    idx2, gnp)) {
659 					gottable->gt_sym = sdp;
660 					gottable->gt_gndx.gn_gotndx =
661 					    gnp->gn_gotndx;
662 					gottable->gt_gndx.gn_addend =
663 					    gnp->gn_addend;
664 					gottable++;
665 				}
666 			}
667 
668 			if ((type = ELF_ST_TYPE(sym->st_info)) == STT_SECTION)
669 				continue;
670 
671 			/*
672 			 * Ignore any symbols that have been marked as invalid
673 			 * during input processing.  Providing these aren't used
674 			 * for relocation they'll just be dropped from the
675 			 * output image.
676 			 */
677 			if (sdp->sd_flags & FLG_SY_INVALID)
678 				continue;
679 
680 			/*
681 			 * If the section that this symbol was associated
682 			 * with has been discarded - then we discard
683 			 * the local symbol along with it.
684 			 */
685 			if (sdp->sd_flags & FLG_SY_ISDISC)
686 				continue;
687 
688 			/*
689 			 * If this symbol is from a different file
690 			 * than the input descriptor we are processing,
691 			 * treat it as if it has FLG_SY_ISDISC set.
692 			 * This happens when sloppy_comdat_reloc()
693 			 * replaces a symbol to a discarded comdat section
694 			 * with an equivalent symbol from a different
695 			 * file. We only want to enter such a symbol
696 			 * once --- as part of the file that actually
697 			 * supplies it.
698 			 */
699 			if (ifl != sdp->sd_file)
700 				continue;
701 
702 			/*
703 			 * Generate an output symbol to represent this input
704 			 * symbol.  Even if the symbol table is to be stripped
705 			 * we still need to update any local symbols that are
706 			 * used during relocation.
707 			 */
708 			enter_in_symtab = symtab &&
709 			    (!(ofl->ofl_flags & FLG_OF_REDLSYM) ||
710 			    sdp->sd_move);
711 			enter_in_ldynsym = ldynsym &&
712 			    ((sym->st_name != 0) || (type == STT_FILE)) &&
713 			    ldynsym_symtype[type] &&
714 			    !(ofl->ofl_flags & FLG_OF_REDLSYM);
715 
716 			_symshndx = NULL;
717 
718 			if (enter_in_symtab) {
719 				if (!dynsym)
720 					sdp->sd_symndx = *symndx;
721 				symtab[symtab_ndx] = *sym;
722 
723 				/*
724 				 * Provided this isn't an unnamed register
725 				 * symbol, update its name.
726 				 */
727 				if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
728 				    symtab[symtab_ndx].st_name) {
729 					(void) st_setstring(strtab,
730 					    sdp->sd_name, &stoff);
731 					symtab[symtab_ndx].st_name = stoff;
732 				}
733 				sdp->sd_flags &= ~FLG_SY_CLEAN;
734 				if (symshndx)
735 					_symshndx = &symshndx[symtab_ndx];
736 				sdp->sd_sym = sym = &symtab[symtab_ndx++];
737 
738 				if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
739 				    (sym->st_shndx == SHN_ABS) &&
740 				    !enter_in_ldynsym)
741 					continue;
742 			} else if (enter_in_ldynsym) {
743 				/*
744 				 * Not using symtab, but we do have ldynsym
745 				 * available.
746 				 */
747 				ldynsym[ldynsym_ndx] = *sym;
748 				(void) st_setstring(dynstr, sdp->sd_name,
749 				    &stoff);
750 				ldynsym[ldynsym_ndx].st_name = stoff;
751 
752 				sdp->sd_flags &= ~FLG_SY_CLEAN;
753 				if (ldynshndx)
754 					_symshndx = &ldynshndx[ldynsym_ndx];
755 				sdp->sd_sym = sym = &ldynsym[ldynsym_ndx];
756 				/* Add it to sort section if it qualifies */
757 				ADD_TO_DYNSORT(sdp, sym, type, ldynsym_ndx);
758 				ldynsym_ndx++;
759 			} else {	/* Not using symtab or ldynsym */
760 				/*
761 				 * If this symbol requires modifying to provide
762 				 * for a relocation or move table update, make
763 				 * a copy of it.
764 				 */
765 				if (!(sdp->sd_flags & FLG_SY_UPREQD) &&
766 				    !(sdp->sd_move))
767 					continue;
768 				if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
769 				    (sym->st_shndx == SHN_ABS))
770 					continue;
771 
772 				if (ld_sym_copy(sdp) == S_ERROR)
773 					return ((Addr)S_ERROR);
774 				sym = sdp->sd_sym;
775 			}
776 
777 			/*
778 			 * Update the symbols contents if necessary.
779 			 */
780 			update_done = 0;
781 			if (type == STT_FILE) {
782 				sdp->sd_shndx = sym->st_shndx = SHN_ABS;
783 				sdp->sd_flags |= FLG_SY_SPECSEC;
784 				update_done = 1;
785 			}
786 
787 			/*
788 			 * If we are expanding the locally bound partially
789 			 * initialized symbols, then update the address here.
790 			 */
791 			if (ofl->ofl_isparexpn &&
792 			    (sdp->sd_flags & FLG_SY_PAREXPN) && !update_done) {
793 				sym->st_shndx = parexpnndx;
794 				sdp->sd_isc = ofl->ofl_isparexpn;
795 				sym->st_value = parexpnaddr;
796 				parexpnaddr += sym->st_size;
797 				if ((flags & FLG_OF_RELOBJ) == 0)
798 					sym->st_value -= parexpnbase;
799 			}
800 
801 			/*
802 			 * If this isn't an UNDEF symbol (ie. an input section
803 			 * is associated), update the symbols value and index.
804 			 */
805 			if (((isc = sdp->sd_isc) != NULL) && !update_done) {
806 				Word	sectndx;
807 
808 				osp = isc->is_osdesc;
809 				/* LINTED */
810 				sym->st_value +=
811 				    (Off)_elf_getxoff(isc->is_indata);
812 				if ((flags & FLG_OF_RELOBJ) == 0) {
813 					sym->st_value += osp->os_shdr->sh_addr;
814 					/*
815 					 * TLS symbols are relative to
816 					 * the TLS segment.
817 					 */
818 					if ((type == STT_TLS) &&
819 					    (ofl->ofl_tlsphdr)) {
820 						sym->st_value -=
821 						    ofl->ofl_tlsphdr->p_vaddr;
822 					}
823 				}
824 				/* LINTED */
825 				if ((sdp->sd_shndx = sectndx =
826 				    elf_ndxscn(osp->os_scn)) >= SHN_LORESERVE) {
827 					if (_symshndx) {
828 						*_symshndx = sectndx;
829 					}
830 					sym->st_shndx = SHN_XINDEX;
831 				} else {
832 					/* LINTED */
833 					sym->st_shndx = sectndx;
834 				}
835 			}
836 
837 			/*
838 			 * If entering the symbol in both the symtab and the
839 			 * ldynsym, then the one in symtab needs to be
840 			 * copied to ldynsym. If it is only in the ldynsym,
841 			 * then the code above already set it up and we have
842 			 * nothing more to do here.
843 			 */
844 			if (enter_in_symtab && enter_in_ldynsym) {
845 				ldynsym[ldynsym_ndx] = *sym;
846 				(void) st_setstring(dynstr, sdp->sd_name,
847 				    &stoff);
848 				ldynsym[ldynsym_ndx].st_name = stoff;
849 
850 				if (_symshndx && ldynshndx)
851 					ldynshndx[ldynsym_ndx] = *_symshndx;
852 
853 				/* Add it to sort section if it qualifies */
854 				ADD_TO_DYNSORT(sdp, sym, type, ldynsym_ndx);
855 
856 				ldynsym_ndx++;
857 			}
858 		}
859 
860 		/*
861 		 * If this input file has undergone object to symbol
862 		 * capabilities conversion, supply any new capabilities symbols.
863 		 * These symbols are copies of the original global symbols, and
864 		 * follow the existing local symbols that are supplied from this
865 		 * input file (which are identified with a preceding STT_FILE).
866 		 */
867 		if (symtab && cdp && cdp->ca_syms) {
868 			Aliste		idx2;
869 			Cap_sym		*csp;
870 
871 			for (APLIST_TRAVERSE(cdp->ca_syms, idx2, csp)) {
872 				Is_desc	*isp;
873 
874 				sdp = csp->cs_sdp;
875 				sym = sdp->sd_sym;
876 
877 				if ((isp = sdp->sd_isc) != NULL) {
878 					Os_desc	*osp = isp->is_osdesc;
879 
880 					/*
881 					 * Update the symbols value.
882 					 */
883 					/* LINTED */
884 					sym->st_value +=
885 					    (Off)_elf_getxoff(isp->is_indata);
886 					if ((flags & FLG_OF_RELOBJ) == 0)
887 						sym->st_value +=
888 						    osp->os_shdr->sh_addr;
889 
890 					/*
891 					 * Update the symbols section index.
892 					 */
893 					sdp->sd_shndx = sym->st_shndx =
894 					    elf_ndxscn(osp->os_scn);
895 				}
896 
897 				symtab[symtab_ndx] = *sym;
898 				(void) st_setstring(strtab, sdp->sd_name,
899 				    &stoff);
900 				symtab[symtab_ndx].st_name = stoff;
901 				sdp->sd_symndx = symtab_ndx++;
902 			}
903 		}
904 	}
905 
906 	symtab_gbl_bndx = symtab_ndx;	/* .symtab index of 1st global entry */
907 
908 	/*
909 	 * Two special symbols are `_init' and `_fini'.  If these are supplied
910 	 * by crti.o then they are used to represent the total concatenation of
911 	 * the `.init' and `.fini' sections.
912 	 *
913 	 * Determine whether any .init or .fini sections exist.  If these
914 	 * sections exist and a dynamic object is being built, but no `_init'
915 	 * or `_fini' symbols are found, then the user is probably building
916 	 * this object directly from ld(1) rather than using a compiler driver
917 	 * that provides the symbols via crt's.
918 	 *
919 	 * If the .init or .fini section exist, and their associated symbols,
920 	 * determine the size of the sections and updated the symbols value
921 	 * accordingly.
922 	 */
923 	if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_INIT_U), SYM_NOHASH, 0,
924 	    ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED) && sdp->sd_isc &&
925 	    (sdp->sd_isc->is_osdesc == iosp)) {
926 		if (ld_sym_copy(sdp) == S_ERROR)
927 			return ((Addr)S_ERROR);
928 		sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
929 
930 	} else if (iosp && !(flags & FLG_OF_RELOBJ)) {
931 		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
932 		    MSG_ORIG(MSG_SYM_INIT_U), MSG_ORIG(MSG_SCN_INIT));
933 	}
934 
935 	if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_FINI_U), SYM_NOHASH, 0,
936 	    ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED) && sdp->sd_isc &&
937 	    (sdp->sd_isc->is_osdesc == fosp)) {
938 		if (ld_sym_copy(sdp) == S_ERROR)
939 			return ((Addr)S_ERROR);
940 		sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
941 
942 	} else if (fosp && !(flags & FLG_OF_RELOBJ)) {
943 		ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
944 		    MSG_ORIG(MSG_SYM_FINI_U), MSG_ORIG(MSG_SCN_FINI));
945 	}
946 
947 	/*
948 	 * Assign .bss information for use with updating COMMON symbols.
949 	 */
950 	if (ofl->ofl_isbss) {
951 		isc = ofl->ofl_isbss;
952 		osp = isc->is_osdesc;
953 
954 		bssaddr = osp->os_shdr->sh_addr +
955 		    (Off)_elf_getxoff(isc->is_indata);
956 		/* LINTED */
957 		bssndx = elf_ndxscn(osp->os_scn);
958 	}
959 
960 #if	defined(_ELF64)
961 	/*
962 	 * For amd64 target, assign .lbss information for use
963 	 * with updating LCOMMON symbols.
964 	 */
965 	if ((ld_targ.t_m.m_mach == EM_AMD64) && ofl->ofl_islbss) {
966 		osp = ofl->ofl_islbss->is_osdesc;
967 
968 		lbssaddr = osp->os_shdr->sh_addr +
969 		    (Off)_elf_getxoff(ofl->ofl_islbss->is_indata);
970 		/* LINTED */
971 		lbssndx = elf_ndxscn(osp->os_scn);
972 	}
973 #endif
974 	/*
975 	 * Assign .tlsbss information for use with updating COMMON symbols.
976 	 */
977 	if (ofl->ofl_istlsbss) {
978 		osp = ofl->ofl_istlsbss->is_osdesc;
979 		tlsbssaddr = osp->os_shdr->sh_addr +
980 		    (Off)_elf_getxoff(ofl->ofl_istlsbss->is_indata);
981 		/* LINTED */
982 		tlsbssndx = elf_ndxscn(osp->os_scn);
983 	}
984 
985 	if ((sorted_syms = libld_calloc(ofl->ofl_globcnt +
986 	    ofl->ofl_elimcnt + ofl->ofl_scopecnt,
987 	    sizeof (*sorted_syms))) == NULL)
988 		return ((Addr)S_ERROR);
989 
990 	scndx = 0;
991 	ssndx = ofl->ofl_scopecnt + ofl->ofl_elimcnt;
992 
993 	DBG_CALL(Dbg_syms_up_title(ofl->ofl_lml));
994 
995 	/*
996 	 * Traverse the internal symbol table updating global symbol information
997 	 * and allocating common.
998 	 */
999 	for (sav = avl_first(&ofl->ofl_symavl); sav;
1000 	    sav = AVL_NEXT(&ofl->ofl_symavl, sav)) {
1001 		Sym	*symptr;
1002 		int	local;
1003 		int	restore;
1004 
1005 		sdp = sav->sav_sdp;
1006 
1007 		/*
1008 		 * Ignore any symbols that have been marked as invalid during
1009 		 * input processing.  Providing these aren't used for
1010 		 * relocation, they will be dropped from the output image.
1011 		 */
1012 		if (sdp->sd_flags & FLG_SY_INVALID) {
1013 			DBG_CALL(Dbg_syms_old(ofl, sdp));
1014 			DBG_CALL(Dbg_syms_ignore(ofl, sdp));
1015 			continue;
1016 		}
1017 
1018 		/*
1019 		 * Only needed symbols are copied to the output symbol table.
1020 		 */
1021 		if (sdp->sd_ref == REF_DYN_SEEN)
1022 			continue;
1023 
1024 		if (ld_sym_reducable(ofl, sdp))
1025 			local = 1;
1026 		else
1027 			local = 0;
1028 
1029 		if (local || (ofl->ofl_hashbkts == 0)) {
1030 			sorted_syms[scndx++].sl_sdp = sdp;
1031 		} else {
1032 			sorted_syms[ssndx].sl_hval = sdp->sd_aux->sa_hash %
1033 			    ofl->ofl_hashbkts;
1034 			sorted_syms[ssndx].sl_sdp = sdp;
1035 			ssndx++;
1036 		}
1037 
1038 		/*
1039 		 * Note - expand the COMMON symbols here because an address
1040 		 * must be assigned to them in the same order that space was
1041 		 * calculated in sym_validate().  If this ordering isn't
1042 		 * followed differing alignment requirements can throw us all
1043 		 * out of whack.
1044 		 *
1045 		 * The expanded .bss global symbol is handled here as well.
1046 		 *
1047 		 * The actual adding entries into the symbol table still occurs
1048 		 * below in hashbucket order.
1049 		 */
1050 		symptr = sdp->sd_sym;
1051 		restore = 0;
1052 		if ((sdp->sd_flags & FLG_SY_PAREXPN) ||
1053 		    ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1054 		    (sdp->sd_shndx = symptr->st_shndx) == SHN_COMMON)) {
1055 
1056 			/*
1057 			 * An expanded symbol goes to a special .data section
1058 			 * prepared for that purpose (ofl->ofl_isparexpn).
1059 			 * Assign COMMON allocations to .bss.
1060 			 * Otherwise leave it as is.
1061 			 */
1062 			if (sdp->sd_flags & FLG_SY_PAREXPN) {
1063 				restore = 1;
1064 				sdp->sd_shndx = parexpnndx;
1065 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1066 				symptr->st_value = (Xword) S_ROUND(
1067 				    parexpnaddr, symptr->st_value);
1068 				parexpnaddr = symptr->st_value +
1069 				    symptr->st_size;
1070 				sdp->sd_isc = ofl->ofl_isparexpn;
1071 				sdp->sd_flags |= FLG_SY_COMMEXP;
1072 
1073 			} else if (ELF_ST_TYPE(symptr->st_info) != STT_TLS &&
1074 			    (local || !(flags & FLG_OF_RELOBJ))) {
1075 				restore = 1;
1076 				sdp->sd_shndx = bssndx;
1077 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1078 				symptr->st_value = (Xword)S_ROUND(bssaddr,
1079 				    symptr->st_value);
1080 				bssaddr = symptr->st_value + symptr->st_size;
1081 				sdp->sd_isc = ofl->ofl_isbss;
1082 				sdp->sd_flags |= FLG_SY_COMMEXP;
1083 
1084 			} else if (ELF_ST_TYPE(symptr->st_info) == STT_TLS &&
1085 			    (local || !(flags & FLG_OF_RELOBJ))) {
1086 				restore = 1;
1087 				sdp->sd_shndx = tlsbssndx;
1088 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1089 				symptr->st_value = (Xword)S_ROUND(tlsbssaddr,
1090 				    symptr->st_value);
1091 				tlsbssaddr = symptr->st_value + symptr->st_size;
1092 				sdp->sd_isc = ofl->ofl_istlsbss;
1093 				sdp->sd_flags |= FLG_SY_COMMEXP;
1094 				/*
1095 				 * TLS symbols are relative to the TLS segment.
1096 				 */
1097 				symptr->st_value -= ofl->ofl_tlsphdr->p_vaddr;
1098 			}
1099 #if	defined(_ELF64)
1100 		} else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
1101 		    (sdp->sd_flags & FLG_SY_SPECSEC) &&
1102 		    ((sdp->sd_shndx = symptr->st_shndx) ==
1103 		    SHN_X86_64_LCOMMON) &&
1104 		    ((local || !(flags & FLG_OF_RELOBJ)))) {
1105 			restore = 1;
1106 			sdp->sd_shndx = lbssndx;
1107 			sdp->sd_flags &= ~FLG_SY_SPECSEC;
1108 			symptr->st_value = (Xword)S_ROUND(lbssaddr,
1109 			    symptr->st_value);
1110 			lbssaddr = symptr->st_value + symptr->st_size;
1111 			sdp->sd_isc = ofl->ofl_islbss;
1112 			sdp->sd_flags |= FLG_SY_COMMEXP;
1113 #endif
1114 		}
1115 
1116 		if (restore != 0) {
1117 			uchar_t		type, bind;
1118 
1119 			/*
1120 			 * Make sure this COMMON symbol is returned to the same
1121 			 * binding as was defined in the original relocatable
1122 			 * object reference.
1123 			 */
1124 			type = ELF_ST_TYPE(symptr->st_info);
1125 			if (sdp->sd_flags & FLG_SY_GLOBREF)
1126 				bind = STB_GLOBAL;
1127 			else
1128 				bind = STB_WEAK;
1129 
1130 			symptr->st_info = ELF_ST_INFO(bind, type);
1131 		}
1132 
1133 #define	IS_DATA_SYMBOL(x)	((ELF_ST_TYPE(x->st_info) == STT_OBJECT) || \
1134 		    (ELF_ST_TYPE(x->st_info) == STT_COMMON) ||		    \
1135 		    (ELF_ST_TYPE(x->st_info) == STT_TLS))
1136 
1137 /*
1138  * Filter symbols, special symbols, and those that will be reduced aren't
1139  * worth guidance
1140  */
1141 #define	IS_BORING_SYMBOL(x)	(x->sd_flags & (FLG_SY_REDUCED|FLG_SY_STDFLTR| \
1142 		    FLG_SY_SPECSEC|FLG_SY_HIDDEN|FLG_SY_ELIM|FLG_SY_IGNORE))
1143 
1144 /* Local symbols and unresolved weaks aren't useful to guide on */
1145 #define	IS_BORING_SCOPE(x)	((ELF_ST_BIND(x->st_info) == STB_LOCAL) || \
1146 		    ((ELF_ST_BIND(x->st_info) == STB_WEAK) &&		   \
1147 		    (x->st_shndx == SHN_UNDEF)))
1148 
1149 /* Symbol has the assertions recommended for global data */
1150 #define	HAS_NEEDED_ASSERTS(x)	((x->sd_ass != NULL) &&		\
1151 		    (ass_enabled(x->sd_ass, SYM_ASSERT_SIZE) ||	\
1152 		    ass_enabled(x->sd_ass, SYM_ASSERT_ALIAS)))
1153 
1154 		/*
1155 		 * If we're building a shared object and a mapfile is
1156 		 * specified, issue guidance if any symbol mentioned in the
1157 		 * mapfile is a global data symbol with no asserted size.
1158 		 *
1159 		 * This is somewhat heuristic to maximize the chance of
1160 		 * -zguidance users seeing our good advice without us being
1161 		 * annoying (eg. we don't guide when things like
1162 		 * mapfile.noex* are the only mapfiles)
1163 		 */
1164 		if (OFL_GUIDANCE(ofl, FLG_OFG_NO_ASSERTS) &&
1165 		    (aplist_nitems(ofl->ofl_maps) > 0) && /* mapfile used */
1166 		    (ofl->ofl_flags & FLG_OF_SHAROBJ) && /* building .so */
1167 		    (ofl->ofl_flags & FLG_OF_VERDEF) && /* versions/reduce */
1168 		    (sdp->sd_ref == REF_REL_NEED) && /* symbol in .o */
1169 		    IS_DATA_SYMBOL(sdp->sd_sym) &&
1170 		    !IS_BORING_SCOPE(sdp->sd_sym) &&
1171 		    !IS_BORING_SYMBOL(sdp) &&
1172 		    !HAS_NEEDED_ASSERTS(sdp)) {
1173 			ld_eprintf(ofl, ERR_GUIDANCE,
1174 			    MSG_INTL(MSG_GUIDE_ASSERT_SIZE),
1175 			    sdp->sd_name, (Lword)sdp->sd_sym->st_size);
1176 		}
1177 	}
1178 
1179 	/*
1180 	 * If this is a dynamic object then add any local capabilities symbols.
1181 	 */
1182 	if (dynsym && ofl->ofl_capfamilies) {
1183 		Cap_avlnode	*cav;
1184 
1185 		for (cav = avl_first(ofl->ofl_capfamilies); cav;
1186 		    cav = AVL_NEXT(ofl->ofl_capfamilies, cav)) {
1187 			Cap_sym		*csp;
1188 			Aliste		idx;
1189 
1190 			for (APLIST_TRAVERSE(cav->cn_members, idx, csp)) {
1191 				sdp = csp->cs_sdp;
1192 
1193 				DBG_CALL(Dbg_syms_created(ofl->ofl_lml,
1194 				    sdp->sd_name));
1195 				DBG_CALL(Dbg_syms_entered(ofl, sdp->sd_sym,
1196 				    sdp));
1197 
1198 				dynsym[dynsym_ndx] = *sdp->sd_sym;
1199 
1200 				(void) st_setstring(dynstr, sdp->sd_name,
1201 				    &stoff);
1202 				dynsym[dynsym_ndx].st_name = stoff;
1203 
1204 				sdp->sd_sym = &dynsym[dynsym_ndx];
1205 				sdp->sd_symndx = dynsym_ndx;
1206 
1207 				/*
1208 				 * Indicate that this is a capabilities symbol.
1209 				 * Note, that this identification only provides
1210 				 * information regarding the symbol that is
1211 				 * visible from elfdump(1) -y.  The association
1212 				 * of a symbol to its capabilities is derived
1213 				 * from a .SUNW_capinfo entry.
1214 				 */
1215 				if (syminfo) {
1216 					syminfo[dynsym_ndx].si_flags |=
1217 					    SYMINFO_FLG_CAP;
1218 				}
1219 
1220 				dynsym_ndx++;
1221 			}
1222 		}
1223 	}
1224 
1225 	if (ofl->ofl_hashbkts) {
1226 		qsort(sorted_syms + ofl->ofl_scopecnt + ofl->ofl_elimcnt,
1227 		    ofl->ofl_globcnt, sizeof (Sym_s_list),
1228 		    (int (*)(const void *, const void *))sym_hash_compare);
1229 	}
1230 
1231 	for (ssndx = 0; ssndx < (ofl->ofl_elimcnt + ofl->ofl_scopecnt +
1232 	    ofl->ofl_globcnt); ssndx++) {
1233 		const char	*name;
1234 		Sym		*sym;
1235 		Sym_aux		*sap;
1236 		Half		spec;
1237 		int		local = 0, dynlocal = 0, enter_in_symtab;
1238 		Gotndx		*gnp;
1239 		Word		sectndx;
1240 
1241 		sdp = sorted_syms[ssndx].sl_sdp;
1242 		sectndx = 0;
1243 
1244 		if (symtab)
1245 			enter_in_symtab = 1;
1246 		else
1247 			enter_in_symtab = 0;
1248 
1249 		/*
1250 		 * Assign a got offset if necessary.
1251 		 */
1252 		if ((ld_targ.t_mr.mr_assign_got != NULL) &&
1253 		    (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR)
1254 			return ((Addr)S_ERROR);
1255 
1256 		if (DBG_ENABLED) {
1257 			Aliste	idx2;
1258 
1259 			for (ALIST_TRAVERSE(sdp->sd_GOTndxs, idx2, gnp)) {
1260 				gottable->gt_sym = sdp;
1261 				gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
1262 				gottable->gt_gndx.gn_addend = gnp->gn_addend;
1263 				gottable++;
1264 			}
1265 
1266 			if (sdp->sd_aux && sdp->sd_aux->sa_PLTGOTndx) {
1267 				gottable->gt_sym = sdp;
1268 				gottable->gt_gndx.gn_gotndx =
1269 				    sdp->sd_aux->sa_PLTGOTndx;
1270 				gottable++;
1271 			}
1272 		}
1273 
1274 		/*
1275 		 * If this symbol has been marked as being reduced to local
1276 		 * scope then it will have to be placed in the scoped portion
1277 		 * of the .symtab.  Retain the appropriate index for use in
1278 		 * version symbol indexing and relocation.
1279 		 */
1280 		if (ld_sym_reducable(ofl, sdp)) {
1281 			local = 1;
1282 			if (!(sdp->sd_flags & FLG_SY_ELIM) && !dynsym)
1283 				sdp->sd_symndx = scopesym_ndx;
1284 			else
1285 				sdp->sd_symndx = 0;
1286 
1287 			if (sdp->sd_flags & FLG_SY_ELIM) {
1288 				enter_in_symtab = 0;
1289 			} else if (ldynsym && sdp->sd_sym->st_name &&
1290 			    ldynsym_symtype[
1291 			    ELF_ST_TYPE(sdp->sd_sym->st_info)]) {
1292 				dynlocal = 1;
1293 			}
1294 		} else {
1295 			sdp->sd_symndx = *symndx;
1296 		}
1297 
1298 		/*
1299 		 * Copy basic symbol and string information.
1300 		 */
1301 		name = sdp->sd_name;
1302 		sap = sdp->sd_aux;
1303 
1304 		/*
1305 		 * If we require to record version symbol indexes, update the
1306 		 * associated version symbol information for all defined
1307 		 * symbols.  If a version definition is required any zero value
1308 		 * symbol indexes would have been flagged as undefined symbol
1309 		 * errors, however if we're just scoping these need to fall into
1310 		 * the base of global symbols.
1311 		 */
1312 		if (sdp->sd_symndx && versym) {
1313 			Half	vndx = 0;
1314 
1315 			if (sdp->sd_flags & FLG_SY_MVTOCOMM) {
1316 				vndx = VER_NDX_GLOBAL;
1317 			} else if (sdp->sd_ref == REF_REL_NEED) {
1318 				vndx = sap->sa_overndx;
1319 
1320 				if ((vndx == 0) &&
1321 				    (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
1322 					if (SYM_IS_HIDDEN(sdp))
1323 						vndx = VER_NDX_LOCAL;
1324 					else
1325 						vndx = VER_NDX_GLOBAL;
1326 				}
1327 			} else if ((sdp->sd_ref == REF_DYN_NEED) &&
1328 			    (sap->sa_dverndx > 0) &&
1329 			    (sap->sa_dverndx <= sdp->sd_file->ifl_vercnt) &&
1330 			    (sdp->sd_file->ifl_verndx != NULL)) {
1331 				/* Use index of verneed record */
1332 				vndx = sdp->sd_file->ifl_verndx
1333 				    [sap->sa_dverndx].vi_overndx;
1334 			}
1335 			versym[sdp->sd_symndx] = vndx;
1336 		}
1337 
1338 		/*
1339 		 * If we are creating the .syminfo section then set per symbol
1340 		 * flags here.
1341 		 */
1342 		if (sdp->sd_symndx && syminfo &&
1343 		    !(sdp->sd_flags & FLG_SY_NOTAVAIL)) {
1344 			int	ndx = sdp->sd_symndx;
1345 			APlist	**alpp = &(ofl->ofl_symdtent);
1346 
1347 			if (sdp->sd_flags & FLG_SY_MVTOCOMM)
1348 				/*
1349 				 * Identify a copy relocation symbol.
1350 				 */
1351 				syminfo[ndx].si_flags |= SYMINFO_FLG_COPY;
1352 
1353 			if (sdp->sd_ref == REF_DYN_NEED) {
1354 				/*
1355 				 * A reference is bound to a needed dependency.
1356 				 * Save the syminfo entry, so that when the
1357 				 * .dynamic section has been updated, a
1358 				 * DT_NEEDED entry can be associated
1359 				 * (see update_osyminfo()).
1360 				 */
1361 				if (aplist_append(alpp, sdp,
1362 				    AL_CNT_OFL_SYMINFOSYMS) == NULL)
1363 					return (0);
1364 
1365 				/*
1366 				 * Flag that the symbol has a direct association
1367 				 * with the external reference (this is an old
1368 				 * tagging, that has no real effect by itself).
1369 				 */
1370 				syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
1371 
1372 				/*
1373 				 * Flag any lazy or deferred reference.
1374 				 */
1375 				if (sdp->sd_flags & FLG_SY_LAZYLD)
1376 					syminfo[ndx].si_flags |=
1377 					    SYMINFO_FLG_LAZYLOAD;
1378 				if (sdp->sd_flags & FLG_SY_DEFERRED)
1379 					syminfo[ndx].si_flags |=
1380 					    SYMINFO_FLG_DEFERRED;
1381 
1382 				/*
1383 				 * Enable direct symbol bindings if:
1384 				 *
1385 				 *  -	Symbol was identified with the DIRECT
1386 				 *	keyword in a mapfile.
1387 				 *
1388 				 *  -	Symbol reference has been bound to a
1389 				 *	dependency which was specified as
1390 				 *	requiring direct bindings with -zdirect.
1391 				 *
1392 				 *  -	All symbol references are required to
1393 				 *	use direct bindings via -Bdirect.
1394 				 */
1395 				if (sdp->sd_flags & FLG_SY_DIR)
1396 					syminfo[ndx].si_flags |=
1397 					    SYMINFO_FLG_DIRECTBIND;
1398 
1399 			} else if ((sdp->sd_flags & FLG_SY_EXTERN) &&
1400 			    (sdp->sd_sym->st_shndx == SHN_UNDEF)) {
1401 				/*
1402 				 * If this symbol has been explicitly defined
1403 				 * as external, and remains unresolved, mark
1404 				 * it as external.
1405 				 */
1406 				syminfo[ndx].si_boundto = SYMINFO_BT_EXTERN;
1407 
1408 			} else if ((sdp->sd_flags & FLG_SY_PARENT) &&
1409 			    (sdp->sd_sym->st_shndx == SHN_UNDEF)) {
1410 				/*
1411 				 * If this symbol has been explicitly defined
1412 				 * to be a reference to a parent object,
1413 				 * indicate whether a direct binding should be
1414 				 * established.
1415 				 */
1416 				syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
1417 				syminfo[ndx].si_boundto = SYMINFO_BT_PARENT;
1418 				if (sdp->sd_flags & FLG_SY_DIR)
1419 					syminfo[ndx].si_flags |=
1420 					    SYMINFO_FLG_DIRECTBIND;
1421 
1422 			} else if (sdp->sd_flags & FLG_SY_STDFLTR) {
1423 				/*
1424 				 * A filter definition.  Although this symbol
1425 				 * can only be a stub, it might be necessary to
1426 				 * prevent external direct bindings.
1427 				 */
1428 				syminfo[ndx].si_flags |= SYMINFO_FLG_FILTER;
1429 				if (sdp->sd_flags & FLG_SY_NDIR)
1430 					syminfo[ndx].si_flags |=
1431 					    SYMINFO_FLG_NOEXTDIRECT;
1432 
1433 			} else if (sdp->sd_flags & FLG_SY_AUXFLTR) {
1434 				/*
1435 				 * An auxiliary filter definition.  By nature,
1436 				 * this definition is direct, in that should the
1437 				 * filtee lookup fail, we'll fall back to this
1438 				 * object.  It may still be necessary to
1439 				 * prevent external direct bindings.
1440 				 */
1441 				syminfo[ndx].si_flags |= SYMINFO_FLG_AUXILIARY;
1442 				if (sdp->sd_flags & FLG_SY_NDIR)
1443 					syminfo[ndx].si_flags |=
1444 					    SYMINFO_FLG_NOEXTDIRECT;
1445 
1446 			} else if ((sdp->sd_ref == REF_REL_NEED) &&
1447 			    (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
1448 				/*
1449 				 * This definition exists within the object
1450 				 * being created.  Provide a default boundto
1451 				 * definition, which may be overridden later.
1452 				 */
1453 				syminfo[ndx].si_boundto = SYMINFO_BT_NONE;
1454 
1455 				/*
1456 				 * Indicate whether it is necessary to prevent
1457 				 * external direct bindings.
1458 				 */
1459 				if (sdp->sd_flags & FLG_SY_NDIR) {
1460 					syminfo[ndx].si_flags |=
1461 					    SYMINFO_FLG_NOEXTDIRECT;
1462 				}
1463 
1464 				/*
1465 				 * Indicate that this symbol is acting as an
1466 				 * individual interposer.
1467 				 */
1468 				if (sdp->sd_flags & FLG_SY_INTPOSE) {
1469 					syminfo[ndx].si_flags |=
1470 					    SYMINFO_FLG_INTERPOSE;
1471 				}
1472 
1473 				/*
1474 				 * Indicate that this symbol is deferred, and
1475 				 * hence should not be bound to during BIND_NOW
1476 				 * relocations.
1477 				 */
1478 				if (sdp->sd_flags & FLG_SY_DEFERRED) {
1479 					syminfo[ndx].si_flags |=
1480 					    SYMINFO_FLG_DEFERRED;
1481 				}
1482 
1483 				/*
1484 				 * If external bindings are allowed, indicate
1485 				 * the binding, and a direct binding if
1486 				 * necessary.
1487 				 */
1488 				if ((sdp->sd_flags & FLG_SY_NDIR) == 0) {
1489 					syminfo[ndx].si_flags |=
1490 					    SYMINFO_FLG_DIRECT;
1491 
1492 					if (sdp->sd_flags & FLG_SY_DIR)
1493 						syminfo[ndx].si_flags |=
1494 						    SYMINFO_FLG_DIRECTBIND;
1495 
1496 					/*
1497 					 * Provide a default boundto definition,
1498 					 * which may be overridden later.
1499 					 */
1500 					syminfo[ndx].si_boundto =
1501 					    SYMINFO_BT_SELF;
1502 				}
1503 
1504 				/*
1505 				 * Indicate that this is a capabilities symbol.
1506 				 * Note, that this identification only provides
1507 				 * information regarding the symbol that is
1508 				 * visible from elfdump(1) -y.  The association
1509 				 * of a symbol to its capabilities is derived
1510 				 * from a .SUNW_capinfo entry.
1511 				 */
1512 				if ((sdp->sd_flags & FLG_SY_CAP) &&
1513 				    ofl->ofl_oscapinfo) {
1514 					syminfo[ndx].si_flags |=
1515 					    SYMINFO_FLG_CAP;
1516 				}
1517 			}
1518 		}
1519 
1520 		/*
1521 		 * Note that the `sym' value is reset to be one of the new
1522 		 * symbol table entries.  This symbol will be updated further
1523 		 * depending on the type of the symbol.  Process the .symtab
1524 		 * first, followed by the .dynsym, thus the `sym' value will
1525 		 * remain as the .dynsym value when the .dynsym is present.
1526 		 * This ensures that any versioning symbols st_name value will
1527 		 * be appropriate for the string table used by version
1528 		 * entries.
1529 		 */
1530 		if (enter_in_symtab) {
1531 			Word	_symndx;
1532 
1533 			if (local)
1534 				_symndx = scopesym_ndx;
1535 			else
1536 				_symndx = symtab_ndx;
1537 
1538 			symtab[_symndx] = *sdp->sd_sym;
1539 			sdp->sd_sym = sym = &symtab[_symndx];
1540 			(void) st_setstring(strtab, name, &stoff);
1541 			sym->st_name = stoff;
1542 		}
1543 		if (dynlocal) {
1544 			ldynsym[ldynscopesym_ndx] = *sdp->sd_sym;
1545 			sdp->sd_sym = sym = &ldynsym[ldynscopesym_ndx];
1546 			(void) st_setstring(dynstr, name, &stoff);
1547 			ldynsym[ldynscopesym_ndx].st_name = stoff;
1548 			/* Add it to sort section if it qualifies */
1549 			ADD_TO_DYNSORT(sdp, sym, ELF_ST_TYPE(sym->st_info),
1550 			    ldynscopesym_ndx);
1551 		}
1552 
1553 		if (dynsym && !local) {
1554 			dynsym[dynsym_ndx] = *sdp->sd_sym;
1555 
1556 			/*
1557 			 * Provided this isn't an unnamed register symbol,
1558 			 * update the symbols name and hash value.
1559 			 */
1560 			if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
1561 			    dynsym[dynsym_ndx].st_name) {
1562 				(void) st_setstring(dynstr, name, &stoff);
1563 				dynsym[dynsym_ndx].st_name = stoff;
1564 
1565 				if (stoff) {
1566 					Word	hashval, _hashndx;
1567 
1568 					hashval =
1569 					    sap->sa_hash % ofl->ofl_hashbkts;
1570 
1571 					/* LINTED */
1572 					if (_hashndx = hashbkt[hashval]) {
1573 						while (hashchain[_hashndx]) {
1574 							_hashndx =
1575 							    hashchain[_hashndx];
1576 						}
1577 						hashchain[_hashndx] =
1578 						    sdp->sd_symndx;
1579 					} else {
1580 						hashbkt[hashval] =
1581 						    sdp->sd_symndx;
1582 					}
1583 				}
1584 			}
1585 			sdp->sd_sym = sym = &dynsym[dynsym_ndx];
1586 
1587 			/*
1588 			 * Add it to sort section if it qualifies.
1589 			 * The indexes in that section are relative to the
1590 			 * the adjacent SUNW_ldynsym/dymsym pair, so we
1591 			 * add the number of items in SUNW_ldynsym to the
1592 			 * dynsym index.
1593 			 */
1594 			ADD_TO_DYNSORT(sdp, sym, ELF_ST_TYPE(sym->st_info),
1595 			    ldynsym_cnt + dynsym_ndx);
1596 		}
1597 
1598 		if (!enter_in_symtab && (!dynsym || (local && !dynlocal))) {
1599 			if (!(sdp->sd_flags & FLG_SY_UPREQD))
1600 				continue;
1601 			sym = sdp->sd_sym;
1602 		} else
1603 			sdp->sd_flags &= ~FLG_SY_CLEAN;
1604 
1605 		/*
1606 		 * If we have a weak data symbol for which we need the real
1607 		 * symbol also, save this processing until later.
1608 		 *
1609 		 * The exception to this is if the weak/strong have PLT's
1610 		 * assigned to them.  In that case we don't do the post-weak
1611 		 * processing because the PLT's must be maintained so that we
1612 		 * can do 'interpositioning' on both of the symbols.
1613 		 */
1614 		if ((sap->sa_linkndx) &&
1615 		    (ELF_ST_BIND(sym->st_info) == STB_WEAK) &&
1616 		    (!sap->sa_PLTndx)) {
1617 			Sym_desc	*_sdp;
1618 
1619 			_sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1620 
1621 			if (_sdp->sd_ref != REF_DYN_SEEN) {
1622 				Wk_desc	wk;
1623 
1624 				if (enter_in_symtab) {
1625 					if (local) {
1626 						wk.wk_symtab =
1627 						    &symtab[scopesym_ndx];
1628 						scopesym_ndx++;
1629 					} else {
1630 						wk.wk_symtab =
1631 						    &symtab[symtab_ndx];
1632 						symtab_ndx++;
1633 					}
1634 				} else {
1635 					wk.wk_symtab = NULL;
1636 				}
1637 				if (dynsym) {
1638 					if (!local) {
1639 						wk.wk_dynsym =
1640 						    &dynsym[dynsym_ndx];
1641 						dynsym_ndx++;
1642 					} else if (dynlocal) {
1643 						wk.wk_dynsym =
1644 						    &ldynsym[ldynscopesym_ndx];
1645 						ldynscopesym_ndx++;
1646 					}
1647 				} else {
1648 					wk.wk_dynsym = NULL;
1649 				}
1650 				wk.wk_weak = sdp;
1651 				wk.wk_alias = _sdp;
1652 
1653 				if (alist_append(&weak, &wk,
1654 				    sizeof (Wk_desc), AL_CNT_WEAK) == NULL)
1655 					return ((Addr)S_ERROR);
1656 
1657 				continue;
1658 			}
1659 		}
1660 
1661 		DBG_CALL(Dbg_syms_old(ofl, sdp));
1662 
1663 		spec = 0;
1664 		/*
1665 		 * assign new symbol value.
1666 		 */
1667 		sectndx = sdp->sd_shndx;
1668 		if (sectndx == SHN_UNDEF) {
1669 			if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) &&
1670 			    (sym->st_value != 0)) {
1671 				ld_eprintf(ofl, ERR_WARNING,
1672 				    MSG_INTL(MSG_SYM_NOTNULL),
1673 				    demangle(name), sdp->sd_file->ifl_name);
1674 			}
1675 
1676 			/*
1677 			 * Undefined weak global, if we are generating a static
1678 			 * executable, output as an absolute zero.  Otherwise
1679 			 * leave it as is, ld.so.1 will skip symbols of this
1680 			 * type (this technique allows applications and
1681 			 * libraries to test for the existence of a symbol as an
1682 			 * indication of the presence or absence of certain
1683 			 * functionality).
1684 			 */
1685 			if (OFL_IS_STATIC_EXEC(ofl) &&
1686 			    (ELF_ST_BIND(sym->st_info) == STB_WEAK)) {
1687 				sdp->sd_flags |= FLG_SY_SPECSEC;
1688 				sdp->sd_shndx = sectndx = SHN_ABS;
1689 			}
1690 		} else if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1691 		    (sectndx == SHN_COMMON)) {
1692 			/* COMMONs have already been processed */
1693 			/* EMPTY */
1694 			;
1695 		} else {
1696 			if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1697 			    (sectndx == SHN_ABS))
1698 				spec = sdp->sd_aux->sa_symspec;
1699 
1700 			/* LINTED */
1701 			if (sdp->sd_flags & FLG_SY_COMMEXP) {
1702 				/*
1703 				 * This is (or was) a COMMON symbol which was
1704 				 * processed above - no processing
1705 				 * required here.
1706 				 */
1707 				;
1708 			} else if (sdp->sd_ref == REF_DYN_NEED) {
1709 				uchar_t	type, bind;
1710 
1711 				sectndx = SHN_UNDEF;
1712 				sym->st_value = 0;
1713 				sym->st_size = 0;
1714 
1715 				/*
1716 				 * Make sure this undefined symbol is returned
1717 				 * to the same binding as was defined in the
1718 				 * original relocatable object reference.
1719 				 */
1720 				type = ELF_ST_TYPE(sym-> st_info);
1721 				if (sdp->sd_flags & FLG_SY_GLOBREF)
1722 					bind = STB_GLOBAL;
1723 				else
1724 					bind = STB_WEAK;
1725 
1726 				sym->st_info = ELF_ST_INFO(bind, type);
1727 
1728 			} else if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1729 			    (sdp->sd_ref == REF_REL_NEED)) {
1730 				osp = sdp->sd_isc->is_osdesc;
1731 				/* LINTED */
1732 				sectndx = elf_ndxscn(osp->os_scn);
1733 
1734 				/*
1735 				 * In an executable, the new symbol value is the
1736 				 * old value (offset into defining section) plus
1737 				 * virtual address of defining section.  In a
1738 				 * relocatable, the new value is the old value
1739 				 * plus the displacement of the section within
1740 				 * the file.
1741 				 */
1742 				/* LINTED */
1743 				sym->st_value +=
1744 				    (Off)_elf_getxoff(sdp->sd_isc->is_indata);
1745 
1746 				if (!(flags & FLG_OF_RELOBJ)) {
1747 					sym->st_value += osp->os_shdr->sh_addr;
1748 					/*
1749 					 * TLS symbols are relative to
1750 					 * the TLS segment.
1751 					 */
1752 					if ((ELF_ST_TYPE(sym->st_info) ==
1753 					    STT_TLS) && (ofl->ofl_tlsphdr))
1754 						sym->st_value -=
1755 						    ofl->ofl_tlsphdr->p_vaddr;
1756 				}
1757 			}
1758 		}
1759 
1760 		if (spec) {
1761 			switch (spec) {
1762 			case SDAUX_ID_ETEXT:
1763 				sym->st_value = etext;
1764 				sectndx = etext_ndx;
1765 				if (etext_abs)
1766 					sdp->sd_flags |= FLG_SY_SPECSEC;
1767 				else
1768 					sdp->sd_flags &= ~FLG_SY_SPECSEC;
1769 				break;
1770 			case SDAUX_ID_EDATA:
1771 				sym->st_value = edata;
1772 				sectndx = edata_ndx;
1773 				if (edata_abs)
1774 					sdp->sd_flags |= FLG_SY_SPECSEC;
1775 				else
1776 					sdp->sd_flags &= ~FLG_SY_SPECSEC;
1777 				break;
1778 			case SDAUX_ID_END:
1779 				sym->st_value = end;
1780 				sectndx = end_ndx;
1781 				if (end_abs)
1782 					sdp->sd_flags |= FLG_SY_SPECSEC;
1783 				else
1784 					sdp->sd_flags &= ~FLG_SY_SPECSEC;
1785 				break;
1786 			case SDAUX_ID_START:
1787 				sym->st_value = start;
1788 				sectndx = start_ndx;
1789 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1790 				break;
1791 			case SDAUX_ID_DYN:
1792 				if (flags & FLG_OF_DYNAMIC) {
1793 					sym->st_value = ofl->
1794 					    ofl_osdynamic->os_shdr->sh_addr;
1795 					/* LINTED */
1796 					sectndx = elf_ndxscn(
1797 					    ofl->ofl_osdynamic->os_scn);
1798 					sdp->sd_flags &= ~FLG_SY_SPECSEC;
1799 				}
1800 				break;
1801 			case SDAUX_ID_PLT:
1802 				if (ofl->ofl_osplt) {
1803 					sym->st_value = ofl->
1804 					    ofl_osplt->os_shdr->sh_addr;
1805 					/* LINTED */
1806 					sectndx = elf_ndxscn(
1807 					    ofl->ofl_osplt->os_scn);
1808 					sdp->sd_flags &= ~FLG_SY_SPECSEC;
1809 				}
1810 				break;
1811 			case SDAUX_ID_GOT:
1812 				/*
1813 				 * Symbol bias for negative growing tables is
1814 				 * stored in symbol's value during
1815 				 * allocate_got().
1816 				 */
1817 				sym->st_value += ofl->
1818 				    ofl_osgot->os_shdr->sh_addr;
1819 				/* LINTED */
1820 				sectndx = elf_ndxscn(ofl->
1821 				    ofl_osgot->os_scn);
1822 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1823 				break;
1824 			case SDAUX_ID_SECBOUND_START:
1825 				sym->st_value = sap->sa_boundsec->
1826 				    os_shdr->sh_addr;
1827 				sectndx = elf_ndxscn(sap->sa_boundsec->os_scn);
1828 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1829 				break;
1830 			case SDAUX_ID_SECBOUND_STOP:
1831 				sym->st_value = sap->sa_boundsec->
1832 				    os_shdr->sh_addr +
1833 				    sap->sa_boundsec->os_shdr->sh_size;
1834 				sectndx = elf_ndxscn(sap->sa_boundsec->os_scn);
1835 				sdp->sd_flags &= ~FLG_SY_SPECSEC;
1836 				break;
1837 			default:
1838 				/* NOTHING */
1839 				;
1840 			}
1841 		}
1842 
1843 		/*
1844 		 * If a plt index has been assigned to an undefined function,
1845 		 * update the symbols value to the appropriate .plt address.
1846 		 */
1847 		if ((flags & FLG_OF_DYNAMIC) && (flags & FLG_OF_EXEC) &&
1848 		    (sdp->sd_file) &&
1849 		    (sdp->sd_file->ifl_ehdr->e_type == ET_DYN) &&
1850 		    (ELF_ST_TYPE(sym->st_info) == STT_FUNC) &&
1851 		    !(flags & FLG_OF_BFLAG)) {
1852 			if (sap->sa_PLTndx)
1853 				sym->st_value =
1854 				    (*ld_targ.t_mr.mr_calc_plt_addr)(sdp, ofl);
1855 		}
1856 
1857 		/*
1858 		 * Finish updating the symbols.
1859 		 */
1860 
1861 		/*
1862 		 * Sym Update: if scoped local - set local binding
1863 		 */
1864 		if (local)
1865 			sym->st_info = ELF_ST_INFO(STB_LOCAL,
1866 			    ELF_ST_TYPE(sym->st_info));
1867 
1868 		/*
1869 		 * Sym Updated: If both the .symtab and .dynsym
1870 		 * are present then we've actually updated the information in
1871 		 * the .dynsym, therefore copy this same information to the
1872 		 * .symtab entry.
1873 		 */
1874 		sdp->sd_shndx = sectndx;
1875 		if (enter_in_symtab && dynsym && (!local || dynlocal)) {
1876 			Word _symndx = dynlocal ? scopesym_ndx : symtab_ndx;
1877 
1878 			symtab[_symndx].st_value = sym->st_value;
1879 			symtab[_symndx].st_size = sym->st_size;
1880 			symtab[_symndx].st_info = sym->st_info;
1881 			symtab[_symndx].st_other = sym->st_other;
1882 		}
1883 
1884 		if (enter_in_symtab) {
1885 			Word	_symndx;
1886 
1887 			if (local)
1888 				_symndx = scopesym_ndx++;
1889 			else
1890 				_symndx = symtab_ndx++;
1891 			if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1892 			    (sectndx >= SHN_LORESERVE)) {
1893 				assert(symshndx != NULL);
1894 				symshndx[_symndx] = sectndx;
1895 				symtab[_symndx].st_shndx = SHN_XINDEX;
1896 			} else {
1897 				/* LINTED */
1898 				symtab[_symndx].st_shndx = (Half)sectndx;
1899 			}
1900 		}
1901 
1902 		if (dynsym && (!local || dynlocal)) {
1903 			/*
1904 			 * dynsym and ldynsym are distinct tables, so
1905 			 * we use indirection to access the right one
1906 			 * and the related extended section index array.
1907 			 */
1908 			Word	_symndx;
1909 			Sym	*_dynsym;
1910 			Word	*_dynshndx;
1911 
1912 			if (!local) {
1913 				_symndx = dynsym_ndx++;
1914 				_dynsym = dynsym;
1915 				_dynshndx = dynshndx;
1916 			} else {
1917 				_symndx = ldynscopesym_ndx++;
1918 				_dynsym = ldynsym;
1919 				_dynshndx = ldynshndx;
1920 			}
1921 			if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1922 			    (sectndx >= SHN_LORESERVE)) {
1923 				assert(_dynshndx != NULL);
1924 				_dynshndx[_symndx] = sectndx;
1925 				_dynsym[_symndx].st_shndx = SHN_XINDEX;
1926 			} else {
1927 				/* LINTED */
1928 				_dynsym[_symndx].st_shndx = (Half)sectndx;
1929 			}
1930 		}
1931 
1932 		DBG_CALL(Dbg_syms_new(ofl, sym, sdp));
1933 	}
1934 
1935 	/*
1936 	 * Now that all the symbols have been processed update any weak symbols
1937 	 * information (ie. copy all information except `st_name').  As both
1938 	 * symbols will be represented in the output, return the weak symbol to
1939 	 * its correct type.
1940 	 */
1941 	for (ALIST_TRAVERSE(weak, idx1, wkp)) {
1942 		Sym_desc	*sdp, *_sdp;
1943 		Sym		*sym, *_sym, *__sym;
1944 		uchar_t		bind;
1945 
1946 		sdp = wkp->wk_weak;
1947 		_sdp = wkp->wk_alias;
1948 		_sym = __sym = _sdp->sd_sym;
1949 
1950 		sdp->sd_flags |= FLG_SY_WEAKDEF;
1951 
1952 		/*
1953 		 * If the symbol definition has been scoped then assign it to
1954 		 * be local, otherwise if it's from a shared object then we need
1955 		 * to maintain the binding of the original reference.
1956 		 */
1957 		if (SYM_IS_HIDDEN(sdp)) {
1958 			if (ld_sym_reducable(ofl, sdp))
1959 				bind = STB_LOCAL;
1960 			else
1961 				bind = STB_WEAK;
1962 		} else if ((sdp->sd_ref == REF_DYN_NEED) &&
1963 		    (sdp->sd_flags & FLG_SY_GLOBREF))
1964 			bind = STB_GLOBAL;
1965 		else
1966 			bind = STB_WEAK;
1967 
1968 		DBG_CALL(Dbg_syms_old(ofl, sdp));
1969 		if ((sym = wkp->wk_symtab) != NULL) {
1970 			sym->st_value = _sym->st_value;
1971 			sym->st_size = _sym->st_size;
1972 			sym->st_other = _sym->st_other;
1973 			sym->st_shndx = _sym->st_shndx;
1974 			sym->st_info = ELF_ST_INFO(bind,
1975 			    ELF_ST_TYPE(sym->st_info));
1976 			__sym = sym;
1977 		}
1978 		if ((sym = wkp->wk_dynsym) != NULL) {
1979 			sym->st_value = _sym->st_value;
1980 			sym->st_size = _sym->st_size;
1981 			sym->st_other = _sym->st_other;
1982 			sym->st_shndx = _sym->st_shndx;
1983 			sym->st_info = ELF_ST_INFO(bind,
1984 			    ELF_ST_TYPE(sym->st_info));
1985 			__sym = sym;
1986 		}
1987 		DBG_CALL(Dbg_syms_new(ofl, __sym, sdp));
1988 	}
1989 
1990 	/*
1991 	 * Now display GOT debugging information if required.
1992 	 */
1993 	DBG_CALL(Dbg_got_display(ofl, 0, 0,
1994 	    ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
1995 
1996 	/*
1997 	 * Update the section headers information. sh_info is
1998 	 * supposed to contain the offset at which the first
1999 	 * global symbol resides in the symbol table, while
2000 	 * sh_link contains the section index of the associated
2001 	 * string table.
2002 	 */
2003 	if (symtab) {
2004 		Shdr	*shdr = ofl->ofl_ossymtab->os_shdr;
2005 
2006 		shdr->sh_info = symtab_gbl_bndx;
2007 		/* LINTED */
2008 		shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osstrtab->os_scn);
2009 		if (symshndx)
2010 			ofl->ofl_ossymshndx->os_shdr->sh_link =
2011 			    (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
2012 
2013 		/*
2014 		 * Ensure that the expected number of symbols
2015 		 * were entered into the right spots:
2016 		 *	- Scoped symbols in the right range
2017 		 *	- Globals start at the right spot
2018 		 *		(correct number of locals entered)
2019 		 *	- The table is exactly filled
2020 		 *		(correct number of globals entered)
2021 		 */
2022 		assert((scopesym_bndx + ofl->ofl_scopecnt) == scopesym_ndx);
2023 		assert(shdr->sh_info == SYMTAB_LOC_CNT(ofl));
2024 		assert((shdr->sh_info + ofl->ofl_globcnt) == symtab_ndx);
2025 	}
2026 	if (dynsym) {
2027 		Shdr	*shdr = ofl->ofl_osdynsym->os_shdr;
2028 
2029 		shdr->sh_info = DYNSYM_LOC_CNT(ofl);
2030 		/* LINTED */
2031 		shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
2032 
2033 		ofl->ofl_oshash->os_shdr->sh_link =
2034 		    /* LINTED */
2035 		    (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
2036 		if (dynshndx) {
2037 			shdr = ofl->ofl_osdynshndx->os_shdr;
2038 			shdr->sh_link =
2039 			    (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
2040 		}
2041 	}
2042 	if (ldynsym) {
2043 		Shdr	*shdr = ofl->ofl_osldynsym->os_shdr;
2044 
2045 		/* ldynsym has no globals, so give index one past the end */
2046 		shdr->sh_info = ldynsym_ndx;
2047 
2048 		/*
2049 		 * The ldynsym and dynsym must be adjacent. The
2050 		 * idea is that rtld should be able to start with
2051 		 * the ldynsym and march straight through the end
2052 		 * of dynsym, seeing them as a single symbol table,
2053 		 * despite the fact that they are in distinct sections.
2054 		 * Ensure that this happened correctly.
2055 		 *
2056 		 * Note that I use ldynsym_ndx here instead of the
2057 		 * computation I used to set the section size
2058 		 * (found in ldynsym_cnt). The two will agree, unless
2059 		 * we somehow miscounted symbols or failed to insert them
2060 		 * all. Using ldynsym_ndx here catches that error in
2061 		 * addition to checking for adjacency.
2062 		 */
2063 		assert(dynsym == (ldynsym + ldynsym_ndx));
2064 
2065 
2066 		/* LINTED */
2067 		shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
2068 
2069 		if (ldynshndx) {
2070 			shdr = ofl->ofl_osldynshndx->os_shdr;
2071 			shdr->sh_link =
2072 			    (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2073 		}
2074 
2075 		/*
2076 		 * The presence of .SUNW_ldynsym means that there may be
2077 		 * associated sort sections, one for regular symbols
2078 		 * and the other for TLS. Each sort section needs the
2079 		 * following done:
2080 		 *	- Section header link references .SUNW_ldynsym
2081 		 *	- Should have received the expected # of items
2082 		 *	- Sorted by increasing address
2083 		 */
2084 		if (ofl->ofl_osdynsymsort) {	/* .SUNW_dynsymsort */
2085 			ofl->ofl_osdynsymsort->os_shdr->sh_link =
2086 			    (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2087 			assert(ofl->ofl_dynsymsortcnt == dynsymsort_ndx);
2088 
2089 			if (dynsymsort_ndx > 1) {
2090 				dynsort_compare_syms = ldynsym;
2091 				qsort(dynsymsort, dynsymsort_ndx,
2092 				    sizeof (*dynsymsort), dynsort_compare);
2093 				dynsort_dupwarn(ofl, ldynsym,
2094 				    st_getstrbuf(dynstr),
2095 				    dynsymsort, dynsymsort_ndx,
2096 				    MSG_ORIG(MSG_SCN_DYNSYMSORT));
2097 			}
2098 		}
2099 		if (ofl->ofl_osdyntlssort) {	/* .SUNW_dyntlssort */
2100 			ofl->ofl_osdyntlssort->os_shdr->sh_link =
2101 			    (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2102 			assert(ofl->ofl_dyntlssortcnt == dyntlssort_ndx);
2103 
2104 			if (dyntlssort_ndx > 1) {
2105 				dynsort_compare_syms = ldynsym;
2106 				qsort(dyntlssort, dyntlssort_ndx,
2107 				    sizeof (*dyntlssort), dynsort_compare);
2108 				dynsort_dupwarn(ofl, ldynsym,
2109 				    st_getstrbuf(dynstr),
2110 				    dyntlssort, dyntlssort_ndx,
2111 				    MSG_ORIG(MSG_SCN_DYNTLSSORT));
2112 			}
2113 		}
2114 	}
2115 
2116 	/*
2117 	 * Used by ld.so.1 only.
2118 	 */
2119 	return (etext);
2120 
2121 #undef ADD_TO_DYNSORT
2122 }
2123 
2124 /*
2125  * Build the dynamic section.
2126  *
2127  * This routine must be maintained in parallel with make_dynamic()
2128  * in sections.c
2129  */
2130 static int
update_odynamic(Ofl_desc * ofl)2131 update_odynamic(Ofl_desc *ofl)
2132 {
2133 	Aliste		idx;
2134 	Ifl_desc	*ifl;
2135 	Sym_desc	*sdp;
2136 	Shdr		*shdr;
2137 	Dyn		*_dyn = (Dyn *)ofl->ofl_osdynamic->os_outdata->d_buf;
2138 	Dyn		*dyn;
2139 	Os_desc		*symosp, *strosp;
2140 	Str_tbl		*strtbl;
2141 	size_t		stoff;
2142 	ofl_flag_t	flags = ofl->ofl_flags;
2143 	int		not_relobj = !(flags & FLG_OF_RELOBJ);
2144 	Word		cnt;
2145 
2146 	/*
2147 	 * Relocatable objects can be built with -r and -dy to trigger the
2148 	 * creation of a .dynamic section.  This model is used to create kernel
2149 	 * device drivers.  The .dynamic section provides a subset of userland
2150 	 * .dynamic entries, typically entries such as DT_NEEDED and DT_RUNPATH.
2151 	 *
2152 	 * Within a dynamic object, any .dynamic string references are to the
2153 	 * .dynstr table.  Within a relocatable object, these strings can reside
2154 	 * within the .strtab.
2155 	 */
2156 	if (OFL_IS_STATIC_OBJ(ofl)) {
2157 		symosp = ofl->ofl_ossymtab;
2158 		strosp = ofl->ofl_osstrtab;
2159 		strtbl = ofl->ofl_strtab;
2160 	} else {
2161 		symosp = ofl->ofl_osdynsym;
2162 		strosp = ofl->ofl_osdynstr;
2163 		strtbl = ofl->ofl_dynstrtab;
2164 	}
2165 
2166 	/* LINTED */
2167 	ofl->ofl_osdynamic->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2168 
2169 	dyn = _dyn;
2170 
2171 	for (APLIST_TRAVERSE(ofl->ofl_sos, idx, ifl)) {
2172 		if ((ifl->ifl_flags &
2173 		    (FLG_IF_IGNORE | FLG_IF_DEPREQD)) == FLG_IF_IGNORE)
2174 			continue;
2175 
2176 		/*
2177 		 * Create and set up the DT_POSFLAG_1 entry here if required.
2178 		 */
2179 		if ((ifl->ifl_flags & MSK_IF_POSFLAG1) &&
2180 		    (ifl->ifl_flags & FLG_IF_NEEDED) && not_relobj) {
2181 			dyn->d_tag = DT_POSFLAG_1;
2182 			if (ifl->ifl_flags & FLG_IF_LAZYLD)
2183 				dyn->d_un.d_val = DF_P1_LAZYLOAD;
2184 			if (ifl->ifl_flags & FLG_IF_GRPPRM)
2185 				dyn->d_un.d_val |= DF_P1_GROUPPERM;
2186 			if (ifl->ifl_flags & FLG_IF_DEFERRED)
2187 				dyn->d_un.d_val |= DF_P1_DEFERRED;
2188 			dyn++;
2189 		}
2190 
2191 		if (ifl->ifl_flags & (FLG_IF_NEEDED | FLG_IF_NEEDSTR))
2192 			dyn->d_tag = DT_NEEDED;
2193 		else
2194 			continue;
2195 
2196 		(void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2197 		dyn->d_un.d_val = stoff;
2198 		/* LINTED */
2199 		ifl->ifl_neededndx = (Half)(((uintptr_t)dyn - (uintptr_t)_dyn) /
2200 		    sizeof (Dyn));
2201 		dyn++;
2202 	}
2203 
2204 	if (not_relobj) {
2205 		if (ofl->ofl_dtsfltrs != NULL) {
2206 			Dfltr_desc	*dftp;
2207 
2208 			for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, idx, dftp)) {
2209 				if (dftp->dft_flag == FLG_SY_AUXFLTR)
2210 					dyn->d_tag = DT_SUNW_AUXILIARY;
2211 				else
2212 					dyn->d_tag = DT_SUNW_FILTER;
2213 
2214 				(void) st_setstring(strtbl, dftp->dft_str,
2215 				    &stoff);
2216 				dyn->d_un.d_val = stoff;
2217 				dftp->dft_ndx = (Half)(((uintptr_t)dyn -
2218 				    (uintptr_t)_dyn) / sizeof (Dyn));
2219 				dyn++;
2220 			}
2221 		}
2222 		if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_INIT_U),
2223 		    SYM_NOHASH, 0, ofl)) != NULL) &&
2224 		    (sdp->sd_ref == REF_REL_NEED) &&
2225 		    (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2226 			dyn->d_tag = DT_INIT;
2227 			dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2228 			dyn++;
2229 		}
2230 		if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_FINI_U),
2231 		    SYM_NOHASH, 0, ofl)) != NULL) &&
2232 		    (sdp->sd_ref == REF_REL_NEED) &&
2233 		    (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2234 			dyn->d_tag = DT_FINI;
2235 			dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2236 			dyn++;
2237 		}
2238 		if (ofl->ofl_soname) {
2239 			dyn->d_tag = DT_SONAME;
2240 			(void) st_setstring(strtbl, ofl->ofl_soname, &stoff);
2241 			dyn->d_un.d_val = stoff;
2242 			dyn++;
2243 		}
2244 		if (ofl->ofl_filtees) {
2245 			if (flags & FLG_OF_AUX) {
2246 				dyn->d_tag = DT_AUXILIARY;
2247 			} else {
2248 				dyn->d_tag = DT_FILTER;
2249 			}
2250 			(void) st_setstring(strtbl, ofl->ofl_filtees, &stoff);
2251 			dyn->d_un.d_val = stoff;
2252 			dyn++;
2253 		}
2254 	}
2255 
2256 	if (ofl->ofl_rpath) {
2257 		(void) st_setstring(strtbl, ofl->ofl_rpath, &stoff);
2258 		dyn->d_tag = DT_RUNPATH;
2259 		dyn->d_un.d_val = stoff;
2260 		dyn++;
2261 		dyn->d_tag = DT_RPATH;
2262 		dyn->d_un.d_val = stoff;
2263 		dyn++;
2264 	}
2265 
2266 	if (not_relobj) {
2267 		Aliste	idx;
2268 		Sg_desc	*sgp;
2269 
2270 		if (ofl->ofl_config) {
2271 			dyn->d_tag = DT_CONFIG;
2272 			(void) st_setstring(strtbl, ofl->ofl_config, &stoff);
2273 			dyn->d_un.d_val = stoff;
2274 			dyn++;
2275 		}
2276 		if (ofl->ofl_depaudit) {
2277 			dyn->d_tag = DT_DEPAUDIT;
2278 			(void) st_setstring(strtbl, ofl->ofl_depaudit, &stoff);
2279 			dyn->d_un.d_val = stoff;
2280 			dyn++;
2281 		}
2282 		if (ofl->ofl_audit) {
2283 			dyn->d_tag = DT_AUDIT;
2284 			(void) st_setstring(strtbl, ofl->ofl_audit, &stoff);
2285 			dyn->d_un.d_val = stoff;
2286 			dyn++;
2287 		}
2288 
2289 		dyn->d_tag = DT_HASH;
2290 		dyn->d_un.d_ptr = ofl->ofl_oshash->os_shdr->sh_addr;
2291 		dyn++;
2292 
2293 		shdr = strosp->os_shdr;
2294 		dyn->d_tag = DT_STRTAB;
2295 		dyn->d_un.d_ptr = shdr->sh_addr;
2296 		dyn++;
2297 
2298 		dyn->d_tag = DT_STRSZ;
2299 		dyn->d_un.d_ptr = shdr->sh_size;
2300 		dyn++;
2301 
2302 		/*
2303 		 * Note, the shdr is set and used in the ofl->ofl_osldynsym case
2304 		 * that follows.
2305 		 */
2306 		shdr = symosp->os_shdr;
2307 		dyn->d_tag = DT_SYMTAB;
2308 		dyn->d_un.d_ptr = shdr->sh_addr;
2309 		dyn++;
2310 
2311 		dyn->d_tag = DT_SYMENT;
2312 		dyn->d_un.d_ptr = shdr->sh_entsize;
2313 		dyn++;
2314 
2315 		if (ofl->ofl_osldynsym) {
2316 			Shdr	*lshdr = ofl->ofl_osldynsym->os_shdr;
2317 
2318 			/*
2319 			 * We have arranged for the .SUNW_ldynsym data to be
2320 			 * immediately in front of the .dynsym data.
2321 			 * This means that you could start at the top
2322 			 * of .SUNW_ldynsym and see the data for both tables
2323 			 * without a break. This is the view we want to
2324 			 * provide for DT_SUNW_SYMTAB, which is why we
2325 			 * add the lengths together.
2326 			 */
2327 			dyn->d_tag = DT_SUNW_SYMTAB;
2328 			dyn->d_un.d_ptr = lshdr->sh_addr;
2329 			dyn++;
2330 
2331 			dyn->d_tag = DT_SUNW_SYMSZ;
2332 			dyn->d_un.d_val = lshdr->sh_size + shdr->sh_size;
2333 			dyn++;
2334 		}
2335 
2336 		if (ofl->ofl_osdynsymsort || ofl->ofl_osdyntlssort) {
2337 			dyn->d_tag = DT_SUNW_SORTENT;
2338 			dyn->d_un.d_val = sizeof (Word);
2339 			dyn++;
2340 		}
2341 
2342 		if (ofl->ofl_osdynsymsort) {
2343 			shdr = ofl->ofl_osdynsymsort->os_shdr;
2344 
2345 			dyn->d_tag = DT_SUNW_SYMSORT;
2346 			dyn->d_un.d_ptr = shdr->sh_addr;
2347 			dyn++;
2348 
2349 			dyn->d_tag = DT_SUNW_SYMSORTSZ;
2350 			dyn->d_un.d_val = shdr->sh_size;
2351 			dyn++;
2352 		}
2353 
2354 		if (ofl->ofl_osdyntlssort) {
2355 			shdr = ofl->ofl_osdyntlssort->os_shdr;
2356 
2357 			dyn->d_tag = DT_SUNW_TLSSORT;
2358 			dyn->d_un.d_ptr = shdr->sh_addr;
2359 			dyn++;
2360 
2361 			dyn->d_tag = DT_SUNW_TLSSORTSZ;
2362 			dyn->d_un.d_val = shdr->sh_size;
2363 			dyn++;
2364 		}
2365 
2366 		/*
2367 		 * Reserve the DT_CHECKSUM entry.  Its value will be filled in
2368 		 * after the complete image is built.
2369 		 */
2370 		dyn->d_tag = DT_CHECKSUM;
2371 		ofl->ofl_checksum = &dyn->d_un.d_val;
2372 		dyn++;
2373 
2374 		/*
2375 		 * Versioning sections: DT_VERDEF and DT_VERNEED.
2376 		 *
2377 		 * The Solaris ld does not produce DT_VERSYM, but the GNU ld
2378 		 * does, in order to support their style of versioning, which
2379 		 * differs from ours:
2380 		 *
2381 		 *	- The top bit of the 16-bit Versym index is
2382 		 *		not part of the version, but is interpreted
2383 		 *		as a "hidden bit".
2384 		 *
2385 		 *	- External (SHN_UNDEF) symbols can have non-zero
2386 		 *		Versym values, which specify versions in
2387 		 *		referenced objects, via the Verneed section.
2388 		 *
2389 		 *	- The vna_other field of the Vernaux structures
2390 		 *		found in the Verneed section are not zero as
2391 		 *		with Solaris, but instead contain the version
2392 		 *		index to be used by Versym indices to reference
2393 		 *		the given external version.
2394 		 *
2395 		 * The Solaris ld, rtld, and elfdump programs all interpret the
2396 		 * presence of DT_VERSYM as meaning that GNU versioning rules
2397 		 * apply to the given file. If DT_VERSYM is not present,
2398 		 * then Solaris versioning rules apply. If we should ever need
2399 		 * to change our ld so that it does issue DT_VERSYM, then
2400 		 * this rule for detecting GNU versioning will no longer work.
2401 		 * In that case, we will have to invent a way to explicitly
2402 		 * specify the style of versioning in use, perhaps via a
2403 		 * new dynamic entry named something like DT_SUNW_VERSIONSTYLE,
2404 		 * where the d_un.d_val value specifies which style is to be
2405 		 * used.
2406 		 */
2407 		if ((flags & (FLG_OF_VERDEF | FLG_OF_NOVERSEC)) ==
2408 		    FLG_OF_VERDEF) {
2409 			shdr = ofl->ofl_osverdef->os_shdr;
2410 
2411 			dyn->d_tag = DT_VERDEF;
2412 			dyn->d_un.d_ptr = shdr->sh_addr;
2413 			dyn++;
2414 			dyn->d_tag = DT_VERDEFNUM;
2415 			dyn->d_un.d_ptr = shdr->sh_info;
2416 			dyn++;
2417 		}
2418 		if ((flags & (FLG_OF_VERNEED | FLG_OF_NOVERSEC)) ==
2419 		    FLG_OF_VERNEED) {
2420 			shdr = ofl->ofl_osverneed->os_shdr;
2421 
2422 			dyn->d_tag = DT_VERNEED;
2423 			dyn->d_un.d_ptr = shdr->sh_addr;
2424 			dyn++;
2425 			dyn->d_tag = DT_VERNEEDNUM;
2426 			dyn->d_un.d_ptr = shdr->sh_info;
2427 			dyn++;
2428 		}
2429 
2430 		if ((flags & FLG_OF_COMREL) && ofl->ofl_relocrelcnt) {
2431 			dyn->d_tag = ld_targ.t_m.m_rel_dt_count;
2432 			dyn->d_un.d_val = ofl->ofl_relocrelcnt;
2433 			dyn++;
2434 		}
2435 		if (flags & FLG_OF_TEXTREL) {
2436 			/*
2437 			 * Only the presence of this entry is used in this
2438 			 * implementation, not the value stored.
2439 			 */
2440 			dyn->d_tag = DT_TEXTREL;
2441 			dyn->d_un.d_val = 0;
2442 			dyn++;
2443 		}
2444 
2445 		if (ofl->ofl_osfiniarray) {
2446 			shdr = ofl->ofl_osfiniarray->os_shdr;
2447 
2448 			dyn->d_tag = DT_FINI_ARRAY;
2449 			dyn->d_un.d_ptr = shdr->sh_addr;
2450 			dyn++;
2451 
2452 			dyn->d_tag = DT_FINI_ARRAYSZ;
2453 			dyn->d_un.d_val = shdr->sh_size;
2454 			dyn++;
2455 		}
2456 
2457 		if (ofl->ofl_osinitarray) {
2458 			shdr = ofl->ofl_osinitarray->os_shdr;
2459 
2460 			dyn->d_tag = DT_INIT_ARRAY;
2461 			dyn->d_un.d_ptr = shdr->sh_addr;
2462 			dyn++;
2463 
2464 			dyn->d_tag = DT_INIT_ARRAYSZ;
2465 			dyn->d_un.d_val = shdr->sh_size;
2466 			dyn++;
2467 		}
2468 
2469 		if (ofl->ofl_ospreinitarray) {
2470 			shdr = ofl->ofl_ospreinitarray->os_shdr;
2471 
2472 			dyn->d_tag = DT_PREINIT_ARRAY;
2473 			dyn->d_un.d_ptr = shdr->sh_addr;
2474 			dyn++;
2475 
2476 			dyn->d_tag = DT_PREINIT_ARRAYSZ;
2477 			dyn->d_un.d_val = shdr->sh_size;
2478 			dyn++;
2479 		}
2480 
2481 		if (ofl->ofl_pltcnt) {
2482 			shdr = ofl->ofl_osplt->os_relosdesc->os_shdr;
2483 
2484 			dyn->d_tag = DT_PLTRELSZ;
2485 			dyn->d_un.d_ptr = shdr->sh_size;
2486 			dyn++;
2487 			dyn->d_tag = DT_PLTREL;
2488 			dyn->d_un.d_ptr = ld_targ.t_m.m_rel_dt_type;
2489 			dyn++;
2490 			dyn->d_tag = DT_JMPREL;
2491 			dyn->d_un.d_ptr = shdr->sh_addr;
2492 			dyn++;
2493 		}
2494 		if (ofl->ofl_pltpad) {
2495 			shdr = ofl->ofl_osplt->os_shdr;
2496 
2497 			dyn->d_tag = DT_PLTPAD;
2498 			if (ofl->ofl_pltcnt) {
2499 				dyn->d_un.d_ptr = shdr->sh_addr +
2500 				    ld_targ.t_m.m_plt_reservsz +
2501 				    ofl->ofl_pltcnt * ld_targ.t_m.m_plt_entsize;
2502 			} else
2503 				dyn->d_un.d_ptr = shdr->sh_addr;
2504 			dyn++;
2505 			dyn->d_tag = DT_PLTPADSZ;
2506 			dyn->d_un.d_val = ofl->ofl_pltpad *
2507 			    ld_targ.t_m.m_plt_entsize;
2508 			dyn++;
2509 		}
2510 		if (ofl->ofl_relocsz) {
2511 			shdr = ofl->ofl_osrelhead->os_shdr;
2512 
2513 			dyn->d_tag = ld_targ.t_m.m_rel_dt_type;
2514 			dyn->d_un.d_ptr = shdr->sh_addr;
2515 			dyn++;
2516 			dyn->d_tag = ld_targ.t_m.m_rel_dt_size;
2517 			dyn->d_un.d_ptr = ofl->ofl_relocsz;
2518 			dyn++;
2519 			dyn->d_tag = ld_targ.t_m.m_rel_dt_ent;
2520 			if (shdr->sh_type == SHT_REL)
2521 				dyn->d_un.d_ptr = sizeof (Rel);
2522 			else
2523 				dyn->d_un.d_ptr = sizeof (Rela);
2524 			dyn++;
2525 		}
2526 		if (ofl->ofl_ossyminfo) {
2527 			shdr = ofl->ofl_ossyminfo->os_shdr;
2528 
2529 			dyn->d_tag = DT_SYMINFO;
2530 			dyn->d_un.d_ptr = shdr->sh_addr;
2531 			dyn++;
2532 			dyn->d_tag = DT_SYMINSZ;
2533 			dyn->d_un.d_val = shdr->sh_size;
2534 			dyn++;
2535 			dyn->d_tag = DT_SYMINENT;
2536 			dyn->d_un.d_val = sizeof (Syminfo);
2537 			dyn++;
2538 		}
2539 		if (ofl->ofl_osmove) {
2540 			shdr = ofl->ofl_osmove->os_shdr;
2541 
2542 			dyn->d_tag = DT_MOVETAB;
2543 			dyn->d_un.d_val = shdr->sh_addr;
2544 			dyn++;
2545 			dyn->d_tag = DT_MOVESZ;
2546 			dyn->d_un.d_val = shdr->sh_size;
2547 			dyn++;
2548 			dyn->d_tag = DT_MOVEENT;
2549 			dyn->d_un.d_val = shdr->sh_entsize;
2550 			dyn++;
2551 		}
2552 		if (ofl->ofl_regsymcnt) {
2553 			int	ndx;
2554 
2555 			for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) {
2556 				if ((sdp = ofl->ofl_regsyms[ndx]) == NULL)
2557 					continue;
2558 
2559 				dyn->d_tag = ld_targ.t_m.m_dt_register;
2560 				dyn->d_un.d_val = sdp->sd_symndx;
2561 				dyn++;
2562 			}
2563 		}
2564 
2565 		for (APLIST_TRAVERSE(ofl->ofl_rtldinfo, idx, sdp)) {
2566 			dyn->d_tag = DT_SUNW_RTLDINF;
2567 			dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2568 			dyn++;
2569 		}
2570 
2571 		if (((sgp = ofl->ofl_osdynamic->os_sgdesc) != NULL) &&
2572 		    (sgp->sg_phdr.p_flags & PF_W) && ofl->ofl_osinterp) {
2573 			dyn->d_tag = DT_DEBUG;
2574 			dyn->d_un.d_ptr = 0;
2575 			dyn++;
2576 		}
2577 
2578 		if (ofl->ofl_oscap) {
2579 			dyn->d_tag = DT_SUNW_CAP;
2580 			dyn->d_un.d_val = ofl->ofl_oscap->os_shdr->sh_addr;
2581 			dyn++;
2582 		}
2583 		if (ofl->ofl_oscapinfo) {
2584 			dyn->d_tag = DT_SUNW_CAPINFO;
2585 			dyn->d_un.d_val = ofl->ofl_oscapinfo->os_shdr->sh_addr;
2586 			dyn++;
2587 		}
2588 		if (ofl->ofl_oscapchain) {
2589 			shdr = ofl->ofl_oscapchain->os_shdr;
2590 
2591 			dyn->d_tag = DT_SUNW_CAPCHAIN;
2592 			dyn->d_un.d_val = shdr->sh_addr;
2593 			dyn++;
2594 			dyn->d_tag = DT_SUNW_CAPCHAINSZ;
2595 			dyn->d_un.d_val = shdr->sh_size;
2596 			dyn++;
2597 			dyn->d_tag = DT_SUNW_CAPCHAINENT;
2598 			dyn->d_un.d_val = shdr->sh_entsize;
2599 			dyn++;
2600 		}
2601 
2602 		if (ofl->ofl_aslr != 0) {
2603 			dyn->d_tag = DT_SUNW_ASLR;
2604 			dyn->d_un.d_val = (ofl->ofl_aslr == 1);
2605 			dyn++;
2606 		}
2607 
2608 		if (flags & FLG_OF_SYMBOLIC) {
2609 			dyn->d_tag = DT_SYMBOLIC;
2610 			dyn->d_un.d_val = 0;
2611 			dyn++;
2612 		}
2613 	}
2614 
2615 	dyn->d_tag = DT_FLAGS;
2616 	dyn->d_un.d_val = ofl->ofl_dtflags;
2617 	dyn++;
2618 
2619 	/*
2620 	 * If -Bdirect was specified, but some NODIRECT symbols were specified
2621 	 * via a mapfile, or -znodirect was used on the command line, then
2622 	 * clear the DF_1_DIRECT flag.  The resultant object will use per-symbol
2623 	 * direct bindings rather than be enabled for global direct bindings.
2624 	 *
2625 	 * If any no-direct bindings exist within this object, set the
2626 	 * DF_1_NODIRECT flag.  ld(1) recognizes this flag when processing
2627 	 * dependencies, and performs extra work to ensure that no direct
2628 	 * bindings are established to the no-direct symbols that exist
2629 	 * within these dependencies.
2630 	 */
2631 	if (ofl->ofl_flags1 & FLG_OF1_NGLBDIR)
2632 		ofl->ofl_dtflags_1 &= ~DF_1_DIRECT;
2633 	if (ofl->ofl_flags1 & FLG_OF1_NDIRECT)
2634 		ofl->ofl_dtflags_1 |= DF_1_NODIRECT;
2635 
2636 	dyn->d_tag = DT_FLAGS_1;
2637 	dyn->d_un.d_val = ofl->ofl_dtflags_1;
2638 	dyn++;
2639 
2640 	dyn->d_tag = DT_SUNW_STRPAD;
2641 	dyn->d_un.d_val = DYNSTR_EXTRA_PAD;
2642 	dyn++;
2643 
2644 	dyn->d_tag = DT_SUNW_LDMACH;
2645 	dyn->d_un.d_val = ld_sunw_ldmach();
2646 	dyn++;
2647 
2648 	if (ofl->ofl_flags & FLG_OF_KMOD) {
2649 		dyn->d_tag = DT_SUNW_KMOD;
2650 		dyn->d_un.d_val = 1;
2651 		dyn++;
2652 	}
2653 
2654 	(*ld_targ.t_mr.mr_mach_update_odynamic)(ofl, &dyn);
2655 
2656 	for (cnt = 1 + DYNAMIC_EXTRA_ELTS; cnt--; dyn++) {
2657 		dyn->d_tag = DT_NULL;
2658 		dyn->d_un.d_val = 0;
2659 	}
2660 
2661 	/*
2662 	 * Ensure that we wrote the right number of entries. If not, we either
2663 	 * miscounted in make_dynamic(), or we did something wrong in this
2664 	 * function.
2665 	 */
2666 	assert((ofl->ofl_osdynamic->os_shdr->sh_size /
2667 	    ofl->ofl_osdynamic->os_shdr->sh_entsize) ==
2668 	    ((uintptr_t)dyn - (uintptr_t)_dyn) / sizeof (*dyn));
2669 
2670 	return (1);
2671 }
2672 
2673 /*
2674  * Build the version definition section
2675  */
2676 static int
update_overdef(Ofl_desc * ofl)2677 update_overdef(Ofl_desc *ofl)
2678 {
2679 	Aliste		idx1;
2680 	Ver_desc	*vdp, *_vdp;
2681 	Verdef		*vdf, *_vdf;
2682 	int		num = 0;
2683 	Os_desc		*strosp;
2684 	Str_tbl		*strtbl;
2685 
2686 	/*
2687 	 * Determine which string table to use.
2688 	 */
2689 	if (OFL_IS_STATIC_OBJ(ofl)) {
2690 		strtbl = ofl->ofl_strtab;
2691 		strosp = ofl->ofl_osstrtab;
2692 	} else {
2693 		strtbl = ofl->ofl_dynstrtab;
2694 		strosp = ofl->ofl_osdynstr;
2695 	}
2696 
2697 	/*
2698 	 * Traverse the version descriptors and update the version structures
2699 	 * to point to the dynstr name in preparation for building the version
2700 	 * section structure.
2701 	 */
2702 	for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2703 		Sym_desc	*sdp;
2704 
2705 		if (vdp->vd_flags & VER_FLG_BASE) {
2706 			const char	*name = vdp->vd_name;
2707 			size_t		stoff;
2708 
2709 			/*
2710 			 * Create a new string table entry to represent the base
2711 			 * version name (there is no corresponding symbol for
2712 			 * this).
2713 			 */
2714 			(void) st_setstring(strtbl, name, &stoff);
2715 			/* LINTED */
2716 			vdp->vd_name = (const char *)stoff;
2717 		} else {
2718 			sdp = ld_sym_find(vdp->vd_name, vdp->vd_hash, 0, ofl);
2719 			/* LINTED */
2720 			vdp->vd_name = (const char *)
2721 			    (uintptr_t)sdp->sd_sym->st_name;
2722 		}
2723 	}
2724 
2725 	_vdf = vdf = (Verdef *)ofl->ofl_osverdef->os_outdata->d_buf;
2726 
2727 	/*
2728 	 * Traverse the version descriptors and update the version section to
2729 	 * reflect each version and its associated dependencies.
2730 	 */
2731 	for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2732 		Aliste		idx2;
2733 		Half		cnt = 1;
2734 		Verdaux		*vdap, *_vdap;
2735 
2736 		_vdap = vdap = (Verdaux *)(vdf + 1);
2737 
2738 		vdf->vd_version = VER_DEF_CURRENT;
2739 		vdf->vd_flags	= vdp->vd_flags & MSK_VER_USER;
2740 		vdf->vd_ndx	= vdp->vd_ndx;
2741 		vdf->vd_hash	= vdp->vd_hash;
2742 
2743 		/* LINTED */
2744 		vdap->vda_name = (uintptr_t)vdp->vd_name;
2745 		vdap++;
2746 		/* LINTED */
2747 		_vdap->vda_next = (Word)((uintptr_t)vdap - (uintptr_t)_vdap);
2748 
2749 		/*
2750 		 * Traverse this versions dependency list generating the
2751 		 * appropriate version dependency entries.
2752 		 */
2753 		for (APLIST_TRAVERSE(vdp->vd_deps, idx2, _vdp)) {
2754 			/* LINTED */
2755 			vdap->vda_name = (uintptr_t)_vdp->vd_name;
2756 			_vdap = vdap;
2757 			vdap++, cnt++;
2758 			/* LINTED */
2759 			_vdap->vda_next = (Word)((uintptr_t)vdap -
2760 			    (uintptr_t)_vdap);
2761 		}
2762 		_vdap->vda_next = 0;
2763 
2764 		/*
2765 		 * Record the versions auxiliary array offset and the associated
2766 		 * dependency count.
2767 		 */
2768 		/* LINTED */
2769 		vdf->vd_aux = (Word)((uintptr_t)(vdf + 1) - (uintptr_t)vdf);
2770 		vdf->vd_cnt = cnt;
2771 
2772 		/*
2773 		 * Record the next versions offset and update the version
2774 		 * pointer.  Remember the previous version offset as the very
2775 		 * last structures next pointer should be null.
2776 		 */
2777 		_vdf = vdf;
2778 		vdf = (Verdef *)vdap, num++;
2779 		/* LINTED */
2780 		_vdf->vd_next = (Word)((uintptr_t)vdf - (uintptr_t)_vdf);
2781 	}
2782 	_vdf->vd_next = 0;
2783 
2784 	/*
2785 	 * Record the string table association with the version definition
2786 	 * section, and the symbol table associated with the version symbol
2787 	 * table (the actual contents of the version symbol table are filled
2788 	 * in during symbol update).
2789 	 */
2790 	/* LINTED */
2791 	ofl->ofl_osverdef->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2792 
2793 	/*
2794 	 * The version definition sections `info' field is used to indicate the
2795 	 * number of entries in this section.
2796 	 */
2797 	ofl->ofl_osverdef->os_shdr->sh_info = num;
2798 
2799 	return (1);
2800 }
2801 
2802 /*
2803  * Finish the version symbol index section
2804  */
2805 static void
update_oversym(Ofl_desc * ofl)2806 update_oversym(Ofl_desc *ofl)
2807 {
2808 	Os_desc		*osp;
2809 
2810 	/*
2811 	 * Record the symbol table associated with the version symbol table.
2812 	 * The contents of the version symbol table are filled in during
2813 	 * symbol update.
2814 	 */
2815 	if (OFL_IS_STATIC_OBJ(ofl))
2816 		osp = ofl->ofl_ossymtab;
2817 	else
2818 		osp = ofl->ofl_osdynsym;
2819 
2820 	/* LINTED */
2821 	ofl->ofl_osversym->os_shdr->sh_link = (Word)elf_ndxscn(osp->os_scn);
2822 }
2823 
2824 /*
2825  * Build the version needed section
2826  */
2827 static int
update_overneed(Ofl_desc * ofl)2828 update_overneed(Ofl_desc *ofl)
2829 {
2830 	Aliste		idx1;
2831 	Ifl_desc	*ifl;
2832 	Verneed		*vnd, *_vnd;
2833 	Os_desc		*strosp;
2834 	Str_tbl		*strtbl;
2835 	Word		num = 0;
2836 
2837 	_vnd = vnd = (Verneed *)ofl->ofl_osverneed->os_outdata->d_buf;
2838 
2839 	/*
2840 	 * Determine which string table is appropriate.
2841 	 */
2842 	if (OFL_IS_STATIC_OBJ(ofl)) {
2843 		strosp = ofl->ofl_osstrtab;
2844 		strtbl = ofl->ofl_strtab;
2845 	} else {
2846 		strosp = ofl->ofl_osdynstr;
2847 		strtbl = ofl->ofl_dynstrtab;
2848 	}
2849 
2850 	/*
2851 	 * Traverse the shared object list looking for dependencies that have
2852 	 * versions defined within them.
2853 	 */
2854 	for (APLIST_TRAVERSE(ofl->ofl_sos, idx1, ifl)) {
2855 		Half		_cnt;
2856 		Word		cnt = 0;
2857 		Vernaux		*_vnap, *vnap;
2858 		size_t		stoff;
2859 
2860 		if (!(ifl->ifl_flags & FLG_IF_VERNEED))
2861 			continue;
2862 
2863 		vnd->vn_version = VER_NEED_CURRENT;
2864 
2865 		(void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2866 		vnd->vn_file = stoff;
2867 
2868 		_vnap = vnap = (Vernaux *)(vnd + 1);
2869 
2870 		/*
2871 		 * Traverse the version index list recording
2872 		 * each version as a needed dependency.
2873 		 */
2874 		for (_cnt = 0; _cnt <= ifl->ifl_vercnt; _cnt++) {
2875 			Ver_index	*vip = &ifl->ifl_verndx[_cnt];
2876 
2877 			if (vip->vi_flags & FLG_VER_REFER) {
2878 				(void) st_setstring(strtbl, vip->vi_name,
2879 				    &stoff);
2880 				vnap->vna_name = stoff;
2881 
2882 				if (vip->vi_desc) {
2883 					vnap->vna_hash = vip->vi_desc->vd_hash;
2884 					vnap->vna_flags =
2885 					    vip->vi_desc->vd_flags;
2886 				} else {
2887 					vnap->vna_hash = 0;
2888 					vnap->vna_flags = 0;
2889 				}
2890 				vnap->vna_other = vip->vi_overndx;
2891 
2892 				/*
2893 				 * If version A inherits version B, then
2894 				 * B is implicit in A. It suffices for ld.so.1
2895 				 * to verify A at runtime and skip B. The
2896 				 * version normalization process sets the INFO
2897 				 * flag for the versions we want ld.so.1 to
2898 				 * skip.
2899 				 */
2900 				if (vip->vi_flags & VER_FLG_INFO)
2901 					vnap->vna_flags |= VER_FLG_INFO;
2902 
2903 				_vnap = vnap;
2904 				vnap++, cnt++;
2905 				_vnap->vna_next =
2906 				    /* LINTED */
2907 				    (Word)((uintptr_t)vnap - (uintptr_t)_vnap);
2908 			}
2909 		}
2910 
2911 		_vnap->vna_next = 0;
2912 
2913 		/*
2914 		 * Record the versions auxiliary array offset and
2915 		 * the associated dependency count.
2916 		 */
2917 		/* LINTED */
2918 		vnd->vn_aux = (Word)((uintptr_t)(vnd + 1) - (uintptr_t)vnd);
2919 		/* LINTED */
2920 		vnd->vn_cnt = (Half)cnt;
2921 
2922 		/*
2923 		 * Record the next versions offset and update the version
2924 		 * pointer.  Remember the previous version offset as the very
2925 		 * last structures next pointer should be null.
2926 		 */
2927 		_vnd = vnd;
2928 		vnd = (Verneed *)vnap, num++;
2929 		/* LINTED */
2930 		_vnd->vn_next = (Word)((uintptr_t)vnd - (uintptr_t)_vnd);
2931 	}
2932 	_vnd->vn_next = 0;
2933 
2934 	/*
2935 	 * Use sh_link to record the associated string table section, and
2936 	 * sh_info to indicate the number of entries contained in the section.
2937 	 */
2938 	/* LINTED */
2939 	ofl->ofl_osverneed->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2940 	ofl->ofl_osverneed->os_shdr->sh_info = num;
2941 
2942 	return (1);
2943 }
2944 
2945 /*
2946  * Update syminfo section.
2947  */
2948 static uintptr_t
update_osyminfo(Ofl_desc * ofl)2949 update_osyminfo(Ofl_desc *ofl)
2950 {
2951 	Os_desc		*symosp, *infosp = ofl->ofl_ossyminfo;
2952 	Syminfo		*sip = infosp->os_outdata->d_buf;
2953 	Shdr		*shdr = infosp->os_shdr;
2954 	char		*strtab;
2955 	Aliste		idx;
2956 	Sym_desc	*sdp;
2957 	Sfltr_desc	*sftp;
2958 
2959 	if (ofl->ofl_flags & FLG_OF_RELOBJ) {
2960 		symosp = ofl->ofl_ossymtab;
2961 		strtab = ofl->ofl_osstrtab->os_outdata->d_buf;
2962 	} else {
2963 		symosp = ofl->ofl_osdynsym;
2964 		strtab = ofl->ofl_osdynstr->os_outdata->d_buf;
2965 	}
2966 
2967 	/* LINTED */
2968 	infosp->os_shdr->sh_link = (Word)elf_ndxscn(symosp->os_scn);
2969 	if (ofl->ofl_osdynamic)
2970 		infosp->os_shdr->sh_info =
2971 		    /* LINTED */
2972 		    (Word)elf_ndxscn(ofl->ofl_osdynamic->os_scn);
2973 
2974 	/*
2975 	 * Update any references with the index into the dynamic table.
2976 	 */
2977 	for (APLIST_TRAVERSE(ofl->ofl_symdtent, idx, sdp))
2978 		sip[sdp->sd_symndx].si_boundto = sdp->sd_file->ifl_neededndx;
2979 
2980 	/*
2981 	 * Update any filtee references with the index into the dynamic table.
2982 	 */
2983 	for (ALIST_TRAVERSE(ofl->ofl_symfltrs, idx, sftp)) {
2984 		Dfltr_desc	*dftp;
2985 
2986 		dftp = alist_item(ofl->ofl_dtsfltrs, sftp->sft_idx);
2987 		sip[sftp->sft_sdp->sd_symndx].si_boundto = dftp->dft_ndx;
2988 	}
2989 
2990 	/*
2991 	 * Display debugging information about section.
2992 	 */
2993 	DBG_CALL(Dbg_syminfo_title(ofl->ofl_lml));
2994 	if (DBG_ENABLED) {
2995 		Word	_cnt, cnt = shdr->sh_size / shdr->sh_entsize;
2996 		Sym	*symtab = symosp->os_outdata->d_buf;
2997 		Dyn	*dyn;
2998 
2999 		if (ofl->ofl_osdynamic)
3000 			dyn = ofl->ofl_osdynamic->os_outdata->d_buf;
3001 		else
3002 			dyn = NULL;
3003 
3004 		for (_cnt = 1; _cnt < cnt; _cnt++) {
3005 			if (sip[_cnt].si_flags || sip[_cnt].si_boundto)
3006 				/* LINTED */
3007 				DBG_CALL(Dbg_syminfo_entry(ofl->ofl_lml, _cnt,
3008 				    &sip[_cnt], &symtab[_cnt], strtab, dyn));
3009 		}
3010 	}
3011 	return (1);
3012 }
3013 
3014 /*
3015  * Build the output elf header.
3016  */
3017 static uintptr_t
update_oehdr(Ofl_desc * ofl)3018 update_oehdr(Ofl_desc * ofl)
3019 {
3020 	Ehdr	*ehdr = ofl->ofl_nehdr;
3021 
3022 	/*
3023 	 * If an entry point symbol has already been established (refer
3024 	 * sym_validate()) simply update the elf header entry point with the
3025 	 * symbols value.  If no entry point is defined it will have been filled
3026 	 * with the start address of the first section within the text segment
3027 	 * (refer update_outfile()).
3028 	 */
3029 	if (ofl->ofl_entry)
3030 		ehdr->e_entry =
3031 		    ((Sym_desc *)(ofl->ofl_entry))->sd_sym->st_value;
3032 
3033 	ehdr->e_ident[EI_DATA] = ld_targ.t_m.m_data;
3034 	ehdr->e_version = ofl->ofl_dehdr->e_version;
3035 
3036 	/*
3037 	 * When generating a relocatable object under -z symbolcap, set the
3038 	 * e_machine to be generic, and remove any e_flags.  Input relocatable
3039 	 * objects may identify alternative e_machine (m.machplus) and e_flags
3040 	 * values.  However, the functions within the created output object
3041 	 * are selected at runtime using the capabilities mechanism, which
3042 	 * supersedes the e-machine and e_flags information.  Therefore,
3043 	 * e_machine and e_flag values are not propagated to the output object,
3044 	 * as these values might prevent the kernel from loading the object
3045 	 * before the runtime linker gets control.
3046 	 */
3047 	if (ofl->ofl_flags & FLG_OF_OTOSCAP) {
3048 		ehdr->e_machine = ld_targ.t_m.m_mach;
3049 		ehdr->e_flags = 0;
3050 	} else {
3051 		/*
3052 		 * Note. it may be necessary to update the e_flags field in the
3053 		 * machine dependent section.
3054 		 */
3055 		ehdr->e_machine = ofl->ofl_dehdr->e_machine;
3056 		ehdr->e_flags = ofl->ofl_dehdr->e_flags;
3057 
3058 		if (ehdr->e_machine != ld_targ.t_m.m_mach) {
3059 			if (ehdr->e_machine != ld_targ.t_m.m_machplus)
3060 				return (S_ERROR);
3061 			if ((ehdr->e_flags & ld_targ.t_m.m_flagsplus) == 0)
3062 				return (S_ERROR);
3063 		}
3064 	}
3065 
3066 	if (ofl->ofl_flags & FLG_OF_SHAROBJ)
3067 		ehdr->e_type = ET_DYN;
3068 	else if (ofl->ofl_flags & FLG_OF_RELOBJ)
3069 		ehdr->e_type = ET_REL;
3070 	else
3071 		ehdr->e_type = ET_EXEC;
3072 
3073 	return (1);
3074 }
3075 
3076 /*
3077  * Perform move table expansion.
3078  */
3079 static void
expand_move(Ofl_desc * ofl,Sym_desc * sdp,Move * mvp)3080 expand_move(Ofl_desc *ofl, Sym_desc *sdp, Move *mvp)
3081 {
3082 	Os_desc		*osp;
3083 	uchar_t		*taddr, *taddr0;
3084 	Sxword		offset;
3085 	Half		cnt;
3086 	uint_t		stride;
3087 
3088 	osp = ofl->ofl_isparexpn->is_osdesc;
3089 	offset = sdp->sd_sym->st_value - osp->os_shdr->sh_addr;
3090 
3091 	taddr0 = taddr = osp->os_outdata->d_buf;
3092 	taddr += offset;
3093 	taddr = taddr + mvp->m_poffset;
3094 
3095 	for (cnt = 0; cnt < mvp->m_repeat; cnt++) {
3096 		/* LINTED */
3097 		DBG_CALL(Dbg_move_expand(ofl->ofl_lml, mvp,
3098 		    (Addr)(taddr - taddr0)));
3099 		stride = (uint_t)mvp->m_stride + 1;
3100 
3101 		/*
3102 		 * Update the target address based upon the move entry size.
3103 		 * This size was validated in ld_process_move().
3104 		 */
3105 		/* LINTED */
3106 		switch (ELF_M_SIZE(mvp->m_info)) {
3107 		case 1:
3108 			/* LINTED */
3109 			*taddr = (uchar_t)mvp->m_value;
3110 			taddr += stride;
3111 			break;
3112 		case 2:
3113 			/* LINTED */
3114 			*((Half *)taddr) = (Half)mvp->m_value;
3115 			taddr += 2 * stride;
3116 			break;
3117 		case 4:
3118 			/* LINTED */
3119 			*((Word *)taddr) = (Word)mvp->m_value;
3120 			taddr += 4 * stride;
3121 			break;
3122 		case 8:
3123 			/* LINTED */
3124 			*((u_longlong_t *)taddr) = mvp->m_value;
3125 			taddr += 8 * stride;
3126 			break;
3127 		}
3128 	}
3129 }
3130 
3131 /*
3132  * Update Move sections.
3133  */
3134 static void
update_move(Ofl_desc * ofl)3135 update_move(Ofl_desc *ofl)
3136 {
3137 	Word		ndx = 0;
3138 	ofl_flag_t	flags = ofl->ofl_flags;
3139 	Move		*omvp;
3140 	Aliste		idx1;
3141 	Sym_desc	*sdp;
3142 
3143 	/*
3144 	 * Determine the index of the symbol table that will be referenced by
3145 	 * the Move section.
3146 	 */
3147 	if (OFL_ALLOW_DYNSYM(ofl))
3148 		/* LINTED */
3149 		ndx = (Word) elf_ndxscn(ofl->ofl_osdynsym->os_scn);
3150 	else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
3151 		/* LINTED */
3152 		ndx = (Word) elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3153 
3154 	/*
3155 	 * Update sh_link of the Move section, and point to the new Move data.
3156 	 */
3157 	if (ofl->ofl_osmove) {
3158 		ofl->ofl_osmove->os_shdr->sh_link = ndx;
3159 		omvp = (Move *)ofl->ofl_osmove->os_outdata->d_buf;
3160 	}
3161 
3162 	/*
3163 	 * Update symbol entry index
3164 	 */
3165 	for (APLIST_TRAVERSE(ofl->ofl_parsyms, idx1, sdp)) {
3166 		Aliste		idx2;
3167 		Mv_desc		*mdp;
3168 
3169 		/*
3170 		 * Expand move table
3171 		 */
3172 		if (sdp->sd_flags & FLG_SY_PAREXPN) {
3173 			const char	*str;
3174 
3175 			if (flags & FLG_OF_STATIC)
3176 				str = MSG_INTL(MSG_PSYM_EXPREASON1);
3177 			else if (ofl->ofl_flags1 & FLG_OF1_NOPARTI)
3178 				str = MSG_INTL(MSG_PSYM_EXPREASON2);
3179 			else
3180 				str = MSG_INTL(MSG_PSYM_EXPREASON3);
3181 
3182 			DBG_CALL(Dbg_move_parexpn(ofl->ofl_lml,
3183 			    sdp->sd_name, str));
3184 
3185 			for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3186 				DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0,
3187 				    mdp->md_move, sdp));
3188 				expand_move(ofl, sdp, mdp->md_move);
3189 			}
3190 			continue;
3191 		}
3192 
3193 		/*
3194 		 * Process move table
3195 		 */
3196 		DBG_CALL(Dbg_move_outmove(ofl->ofl_lml, sdp->sd_name));
3197 
3198 		for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3199 			Move	*imvp;
3200 			int	idx = 1;
3201 			Sym	*sym;
3202 
3203 			imvp = mdp->md_move;
3204 			sym = sdp->sd_sym;
3205 
3206 			DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 1, imvp, sdp));
3207 
3208 			*omvp = *imvp;
3209 			if ((flags & FLG_OF_RELOBJ) == 0) {
3210 				if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
3211 					Os_desc	*osp = sdp->sd_isc->is_osdesc;
3212 					Word	ndx = osp->os_identndx;
3213 
3214 					omvp->m_info =
3215 					    /* LINTED */
3216 					    ELF_M_INFO(ndx, imvp->m_info);
3217 
3218 					if (ELF_ST_TYPE(sym->st_info) !=
3219 					    STT_SECTION) {
3220 						omvp->m_poffset =
3221 						    sym->st_value -
3222 						    osp->os_shdr->sh_addr +
3223 						    imvp->m_poffset;
3224 					}
3225 				} else {
3226 					omvp->m_info =
3227 					    /* LINTED */
3228 					    ELF_M_INFO(sdp->sd_symndx,
3229 					    imvp->m_info);
3230 				}
3231 			} else {
3232 				Boolean		isredloc = FALSE;
3233 
3234 				if ((ELF_ST_BIND(sym->st_info) == STB_LOCAL) &&
3235 				    (ofl->ofl_flags & FLG_OF_REDLSYM))
3236 					isredloc = TRUE;
3237 
3238 				if (isredloc && !(sdp->sd_move)) {
3239 					Os_desc	*osp = sdp->sd_isc->is_osdesc;
3240 					Word	ndx = osp->os_identndx;
3241 
3242 					omvp->m_info =
3243 					    /* LINTED */
3244 					    ELF_M_INFO(ndx, imvp->m_info);
3245 
3246 					omvp->m_poffset += sym->st_value;
3247 				} else {
3248 					if (isredloc)
3249 						DBG_CALL(Dbg_syms_reduce(ofl,
3250 						    DBG_SYM_REDUCE_RETAIN,
3251 						    sdp, idx,
3252 						    ofl->ofl_osmove->os_name));
3253 
3254 					omvp->m_info =
3255 					    /* LINTED */
3256 					    ELF_M_INFO(sdp->sd_symndx,
3257 					    imvp->m_info);
3258 				}
3259 			}
3260 
3261 			DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0, omvp, sdp));
3262 			omvp++;
3263 			idx++;
3264 		}
3265 	}
3266 }
3267 
3268 /*
3269  * Scan through the SHT_GROUP output sections.  Update their sh_link/sh_info
3270  * fields as well as the section contents.
3271  */
3272 static uintptr_t
update_ogroup(Ofl_desc * ofl)3273 update_ogroup(Ofl_desc *ofl)
3274 {
3275 	Aliste		idx;
3276 	Os_desc		*osp;
3277 	uintptr_t	error = 0;
3278 
3279 	for (APLIST_TRAVERSE(ofl->ofl_osgroups, idx, osp)) {
3280 		Is_desc		*isp;
3281 		Ifl_desc	*ifl;
3282 		Shdr		*shdr = osp->os_shdr;
3283 		Sym_desc	*sdp;
3284 		Xword		i, grpcnt;
3285 		Word		*gdata;
3286 
3287 		/*
3288 		 * Since input GROUP sections always create unique
3289 		 * output GROUP sections - we know there is only one
3290 		 * item on the list.
3291 		 */
3292 		isp = ld_os_first_isdesc(osp);
3293 
3294 		ifl = isp->is_file;
3295 		sdp = ifl->ifl_oldndx[isp->is_shdr->sh_info];
3296 		shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3297 		shdr->sh_info = sdp->sd_symndx;
3298 
3299 		/*
3300 		 * Scan through the group data section and update
3301 		 * all of the links to new values.
3302 		 */
3303 		grpcnt = shdr->sh_size / shdr->sh_entsize;
3304 		gdata = (Word *)osp->os_outdata->d_buf;
3305 
3306 		for (i = 1; i < grpcnt; i++) {
3307 			Is_desc	*_isp = ifl->ifl_isdesc[gdata[i]];
3308 			Os_desc	*_osp = _isp->is_osdesc;
3309 
3310 			/*
3311 			 * If a section in the group is not part of the output
3312 			 * image, something has gone wrong, and corrupted this
3313 			 * group.
3314 			 */
3315 			if (_osp == NULL) {
3316 				ld_eprintf(