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