xref: /illumos-gate/usr/src/cmd/sgs/libld/common/map_support.c (revision b1d7ec75953cd517f5b7c3d9cb427ff8ec5d7d07)
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 2010 Sun Microsystems, Inc.  All rights reserved.
27  * Use is subject to license terms.
28  */
29 
30 /*
31  * Map file parsing (Shared Support Code).
32  */
33 #include	<stdio.h>
34 #include	<errno.h>
35 #include	"msg.h"
36 #include	"_libld.h"
37 #include	"_map.h"
38 
39 /*
40  * Given a NULL terminated array of structures of arbitrary type, where
41  * each struct contains (among other fields) a character pointer field
42  * giving that struct a unique name, return the address of the struct
43  * that matches the given name.
44  *
45  * entry:
46  *	name - "Keyword" name to be found.
47  *	array - Base address of array
48  *	name_offset - Offset of the name field within the struct
49  *		type used by this array, as generated via
50  *		SGSOFFSETOF().
51  *	elt_size - sizeof the basic array element type
52  *
53  * exit:
54  *	Using a case insensitive comparison, name is compared to the
55  *	name of each element of the array. The address of the first
56  *	match found is returned. If the desired name is not found,
57  *	NULL is returned.
58  *
59  * note:
60  *	This routine is completely type-unsafe. The upside is that this
61  *	single routine is able to search arrays of arbitrary type, leaving
62  *	the caller free to structure their array in any way that is convenient
63  *	to solve the problem at hand.
64  */
65 #ifndef _ELF64
66 void *
67 ld_map_kwfind(const char *name, void *array, size_t name_offset,
68     size_t elt_size)
69 {
70 	for (; ; array = elt_size + (char *)array) {
71 		/* LINTED E_BAD_PTR_CAST_ALIGN */
72 		const char *arr_name = *((const char **)
73 		    (name_offset + (const char *) array));
74 
75 		if (arr_name == NULL)
76 			return (NULL);
77 
78 		if (strcasecmp(name, arr_name) == 0)
79 			return (array);
80 	}
81 
82 	/*NOTREACHED*/
83 	assert(0);
84 	return (NULL);
85 }
86 #endif
87 
88 /*
89  * Given the same NULL terminated array accepted by ld_map_kwfind(), format
90  * the strings into a comma separated list of names.
91  *
92  * entry:
93  *	array - Base address of array
94  *	name_offset - Offset of the name field within the struct
95  *		type used by this array, as generated via
96  *		SGSOFFSETOF().
97  *	elt_size - sizeof the basic array element type
98  *	buf - Buffer to receive output
99  *	bufsize - sizeof(buf)
100  *
101  * exit:
102  *	As many of the names as will fit are formatted into buf. If all the
103  *	names do not fit, the remainder are quietly clipped. The caller must
104  *	ensure that there is sufficient room. buf is returned, for convenience
105  *	in using this function as an argument for printing.
106  */
107 #ifndef _ELF64
108 char *
109 ld_map_kwnames(void *array, size_t name_offset, size_t elt_size, char *buf,
110     size_t bufsize)
111 {
112 	size_t	cnt = 0;
113 	size_t	len;
114 	char	*str = buf;
115 
116 	for (; bufsize > 1; array = elt_size + (char *)array, cnt++) {
117 		/* LINTED E_BAD_PTR_CAST_ALIGN */
118 		const char *arr_name = *((const char **)
119 		    (name_offset + (const char *) array));
120 
121 		if (arr_name == NULL)
122 			break;
123 
124 		if (cnt > 0) {
125 			if (bufsize < 3)
126 				break;
127 			*str++ = ',';
128 			*str++ = ' ';
129 			bufsize -= 2;
130 			*(str + 1) = '\0';
131 		}
132 
133 		len = strlcpy(str, arr_name, bufsize);
134 		if (len >= bufsize)
135 			break;
136 		str += len;
137 		bufsize -= len;
138 	}
139 
140 	return (buf);
141 }
142 #endif
143 
144 /*
145  * Create a pseudo input file descriptor to represent the specified Mapfile.
146  * An input descriptor is required any time a symbol is generated.
147  *
148  * entry:
149  *	mf - Mapfile descriptor.
150  *
151  * exit:
152  *	If an input descriptor was already created for this mapfile
153  *	by a previous call, it is returned. Otherwise, a new descriptor
154  *	is created, entered into the mapfile descriptor, and returned.
155  *
156  *	Success is indicated by a non-NULL return value, failure by NULL.
157  */
158 Ifl_desc *
159 ld_map_ifl(Mapfile *mf)
160 {
161 	Ifl_desc	*ifl;
162 
163 	/*
164 	 * If we've already created a pseudo input descriptor for this
165 	 * mapfile, reuse it.
166 	 */
167 	if (mf->mf_ifl != NULL)
168 		return (mf->mf_ifl);
169 
170 	if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == NULL)
171 		return (NULL);
172 	ifl->ifl_name = mf->mf_name;
173 	ifl->ifl_flags = (FLG_IF_MAPFILE | FLG_IF_NEEDED | FLG_IF_FILEREF);
174 	if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 1)) == NULL)
175 		return (NULL);
176 	ifl->ifl_ehdr->e_type = ET_REL;
177 
178 	if (aplist_append(&mf->mf_ofl->ofl_objs, ifl, AL_CNT_OFL_OBJS) == NULL)
179 		return (NULL);
180 
181 	mf->mf_ifl = ifl;
182 	return (mf->mf_ifl);
183 }
184 
185 /*
186  * Given a capability tag type, set the override bit in the output descriptor.
187  * This prevents the use of capability values of that type from the input
188  * objects.
189  */
190 void
191 ld_map_cap_set_ovflag(Mapfile *mf, Word type)
192 {
193 	/*
194 	 * Map capability tag to the corresponding output descriptor
195 	 * override flag.
196 	 */
197 	static ofl_flag_t override_flag[CA_SUNW_NUM] = {
198 		0, 			/* CA_SUNW_NULL */
199 		FLG_OF1_OVHWCAP1,	/* CA_SUNW_HW_1 */
200 		FLG_OF1_OVSFCAP1,	/* CA_SUNW_SF_1 */
201 		FLG_OF1_OVHWCAP2,	/* CA_SUNW_HW_2 */
202 		FLG_OF1_OVPLATCAP,	/* CA_SUNW_PLAT */
203 		FLG_OF1_OVMACHCAP,	/* CA_SUNW_MACH */
204 		FLG_OF1_OVIDCAP		/* CA_SUNW_ID */
205 	};
206 #if CA_SUNW_NUM != (CA_SUNW_ID + 1)
207 #error "CA_SUNW_NUM has grown"
208 #endif
209 	mf->mf_ofl->ofl_flags1 |= override_flag[type];
210 }
211 
212 /*
213  * Sanity check the given capability bitmask.
214  */
215 Boolean
216 ld_map_cap_sanitize(Mapfile *mf, Word type, Capmask *capmask)
217 {
218 	elfcap_mask_t	mask;
219 
220 	switch (type) {
221 	case CA_SUNW_SF_1:
222 		/*
223 		 * Unlike hardware capabilities, we do not allow setting
224 		 * software capability bits that do not have known definitions.
225 		 * Software capability tokens have to be validated as a unit
226 		 * as the bits can affect each others meaning (see sf1_cap()
227 		 * in files.c).
228 		 */
229 		if ((mask = (capmask->cm_val & ~SF1_SUNW_MASK)) != 0) {
230 			mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
231 			    EC_XWORD(mask));
232 			capmask->cm_val &= SF1_SUNW_MASK;
233 		}
234 		if ((capmask->cm_val &
235 		    (SF1_SUNW_FPKNWN | SF1_SUNW_FPUSED)) == SF1_SUNW_FPUSED) {
236 			mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
237 			    EC_XWORD(SF1_SUNW_FPUSED));
238 			capmask->cm_val &= ~SF1_SUNW_FPUSED;
239 		}
240 #if	!defined(_ELF64)
241 		/*
242 		 * The SF1_SUNW_ADDR32 software capability is only meaningful
243 		 * when building a 64-bit object.  Warn the user, and remove the
244 		 * setting, if we're building a 32-bit object.
245 		 */
246 		if (capmask->cm_val & SF1_SUNW_ADDR32) {
247 			mf_warn0(mf, MSG_INTL(MSG_MAP_INADDR32SF1));
248 			capmask->cm_val &= ~SF1_SUNW_ADDR32;
249 		}
250 #endif
251 	}
252 
253 	return (TRUE);
254 }
255 
256 /*
257  * Return the shared object control definition structure (ofl_socntl)
258  * for the specified object, creating one if necessary.
259  *
260  * entry:
261  *	mf - Mapfile descriptor
262  *	obj_name - Name of object
263  *
264  * exit:
265  *	Returns the pointer to the definition structure, or NULL on error.
266  */
267 Sdf_desc *
268 ld_map_dv(Mapfile *mf, const char *obj_name)
269 {
270 	Sdf_desc	*sdf;
271 
272 	/*
273 	 * If a shared object definition for this file already exists use it,
274 	 * otherwise allocate a new descriptor.
275 	 */
276 	if ((sdf = sdf_find(obj_name, mf->mf_ofl->ofl_socntl)) == NULL) {
277 		if ((sdf = sdf_add(obj_name, &mf->mf_ofl->ofl_socntl)) ==
278 		    (Sdf_desc *)S_ERROR)
279 			return (NULL);
280 		sdf->sdf_rfile = mf->mf_name;
281 	}
282 
283 	DBG_CALL(Dbg_map_dv(mf->mf_ofl->ofl_lml, sdf->sdf_name,
284 	    mf->mf_lineno));
285 	return (sdf);
286 }
287 
288 
289 Boolean
290 ld_map_dv_entry(Mapfile *mf, Sdf_desc *sdf, Boolean require,
291     const char *version)
292 {
293 	Sdv_desc	sdv;
294 
295 	sdv.sdv_name = version;
296 	sdv.sdv_ref = mf->mf_name;
297 	sdv.sdv_flags = 0;
298 
299 
300 	if (require) {
301 		/*
302 		 * Add a VERNEED entry for the specified version
303 		 * from this object:
304 		 *
305 		 *	MapfileVersion	Syntax
306 		 *	----------------------------------------
307 		 *	1		obj - $ADDVERS=version;
308 		 *	2		DEPENDENCY obj { REQUIRE=version };
309 		 */
310 		sdf->sdf_flags |= FLG_SDF_ADDVER;
311 
312 		if (alist_append(&sdf->sdf_verneed, &sdv, sizeof (Sdv_desc),
313 		    AL_CNT_SDF_VERSIONS) == NULL)
314 			return (FALSE);
315 	} else {		/* Allow */
316 		/*
317 		 * Allow linking to symbols found in this version, or
318 		 * from the versions it inherits from.
319 		 *
320 		 *	MapfileVersion	Syntax
321 		 *	----------------------------------------
322 		 *	1		obj - version;
323 		 *	2		DEPENDENCY obj { ALLOW=version };
324 		 */
325 		sdf->sdf_flags |= FLG_SDF_SELECT;
326 
327 		if (alist_append(&sdf->sdf_vers, &sdv, sizeof (Sdv_desc),
328 		    AL_CNT_SDF_VERSIONS) == NULL)
329 			return (FALSE);
330 	}
331 
332 	DBG_CALL(Dbg_map_dv_entry(mf->mf_ofl->ofl_lml, mf->mf_lineno,
333 	    require, version));
334 
335 	return (TRUE);
336 }
337 
338 /*
339  * Given a segment descriptor, return its index.
340  *
341  * entry:
342  *	mf - Mapfile descriptor
343  *	sgp - Segment for which index is desired
344  *
345  * exit:
346  *	Index of segment is returned.
347  */
348 Xword
349 ld_map_seg_index(Mapfile *mf, Sg_desc *sgp)
350 {
351 	Aliste		idx;
352 	Sg_desc		*sgp2;
353 	Ofl_desc	*ofl = mf->mf_ofl;
354 
355 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2))
356 		if (sgp == sgp2)
357 			break;
358 
359 	return (idx);
360 }
361 
362 /*
363  * Add a section name to the output section sort list for the given
364  * segment.
365  *
366  * entry:
367  *	mf - Mapfile descriptor
368  *	sgp - Segment in question
369  *	sec_name - Name of section to be added.
370  *
371  * exit:
372  *	Returns TRUE for success, FALSE for failure.
373  */
374 Boolean
375 ld_map_seg_os_order_add(Mapfile *mf, Sg_desc *sgp, const char *sec_name)
376 {
377 	Aliste		idx;
378 	Sec_order	*scop;
379 
380 	/*
381 	 * Make sure it's not already on the list
382 	 */
383 	for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop))
384 		if (strcmp(scop->sco_secname, sec_name) == 0) {
385 			mf_fatal(mf, MSG_INTL(MSG_MAP_DUP_OS_ORD), sec_name);
386 			return (FALSE);
387 		}
388 
389 
390 	scop = alist_append(&sgp->sg_os_order, NULL, sizeof (Sec_order),
391 	    AL_CNT_SG_SECORDER);
392 	if (scop == NULL)
393 		return (FALSE);
394 
395 	scop->sco_secname = sec_name;
396 
397 	DBG_CALL(Dbg_map_seg_os_order(mf->mf_ofl->ofl_lml, sgp, sec_name,
398 	    alist_nitems(sgp->sg_os_order), mf->mf_lineno));
399 
400 	/*
401 	 * Output section ordering is a relatively expensive operation,
402 	 * and one that is generally not used. In order to avoid needless
403 	 * work, the FLG_OF_OS_ORDER must be set when it will be needed.
404 	 * The section we just added needs this flag to be set. However,
405 	 * it is possible that a subsequent mapfile directive may come
406 	 * along and clear the order list, making it unnecessary.
407 	 *
408 	 * Instead of setting it here, we do a final pass over the segments
409 	 * in ld_map_finalize() and set it there if a segment with sorting
410 	 * requirements is seen.
411 	 */
412 
413 	return (TRUE);
414 }
415 
416 /*
417  * Add a size symbol to a segment
418  *
419  * entry:
420  *	mf - Mapfile descriptor
421  *	sgp - Segment descriptor
422  *	eq_tol - Type of assignment: TK_EQUAL, or TK_PLUSEQ
423  *	symname - Name of symbol. Must be in stable static storage
424  *		that can be retained.
425  *
426  * exit:
427  *	On success, the symbol has been added and TRUE is returned.
428  *	Otherwise an error is reported and FALSE is returned.
429  */
430 Boolean
431 ld_map_seg_size_symbol(Mapfile *mf, Sg_desc *sgp, Token eq_tok,
432     const char *symname)
433 {
434 	Sym		*sym;		/* New symbol pointer */
435 	Sym_desc	*sdp;		/* New symbol node pointer */
436 	Ifl_desc	*ifl;		/* Dummy input file structure */
437 	avl_index_t	where;
438 	Ofl_desc	*ofl = mf->mf_ofl;
439 
440 	/*
441 	 * We don't allow resetting the list of size symbols, so if the
442 	 * operator is TK_EQUAL and the list is not empty, issue an error.
443 	 *
444 	 * If we want to lift this restriction, we would have to save the
445 	 * size symbols and enter them from ld_map_post_process(). Doing that
446 	 * well would require a significant overhead in saved error reporting
447 	 * state, and interactions with the same symbols created by symbol
448 	 * directives. As size symbols are of little practical use, and are
449 	 * maintained primarily for backward compatibility with SysV, we have
450 	 * decided not to do that, but to create the symbols as the mapfiles
451 	 * are processed, and to disallow later attempts to remove them.
452 	 */
453 	if ((eq_tok == TK_EQUAL) && (aplist_nitems(sgp->sg_sizesym) > 0)) {
454 		mf_fatal(mf, MSG_INTL(MSG_MAP_SEGSIZE), sgp->sg_name);
455 		return (FALSE);
456 	}
457 
458 	/*
459 	 * Make sure we have a pseudo file descriptor to associate to the
460 	 * symbol.
461 	 */
462 	if ((ifl = ld_map_ifl(mf)) == NULL)
463 		return (FALSE);
464 
465 	/*
466 	 * Make sure the symbol doesn't already exist.  It is possible that the
467 	 * symbol has been scoped or versioned, in which case it does exist
468 	 * but we can freely update it here.
469 	 */
470 	if ((sdp = ld_sym_find(symname, SYM_NOHASH, &where, ofl)) == NULL) {
471 		Word hval;
472 
473 		if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
474 			return (FALSE);
475 		sym->st_shndx = SHN_ABS;
476 		sym->st_size = 0;
477 		sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
478 
479 		DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, symname,
480 		    sgp->sg_name, mf->mf_lineno));
481 		/* LINTED */
482 		hval = (Word)elf_hash(symname);
483 		if ((sdp = ld_sym_enter(symname, sym, hval, ifl, ofl, 0,
484 		    SHN_ABS, (FLG_SY_SPECSEC | FLG_SY_GLOBREF), &where)) ==
485 		    (Sym_desc *)S_ERROR)
486 			return (FALSE);
487 		sdp->sd_flags &= ~FLG_SY_CLEAN;
488 		DBG_CALL(Dbg_map_symbol(ofl, sdp));
489 	} else {
490 		sym = sdp->sd_sym;
491 
492 		if (sym->st_shndx == SHN_UNDEF) {
493 			sdp->sd_shndx = sym->st_shndx = SHN_ABS;
494 			sdp->sd_flags |= FLG_SY_SPECSEC;
495 			sym->st_size = 0;
496 			sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
497 
498 			sdp->sd_flags &= ~FLG_SY_MAPREF;
499 
500 			DBG_CALL(Dbg_map_size_old(ofl, sdp,
501 			    sgp->sg_name, mf->mf_lineno));
502 		} else {
503 			mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
504 			    demangle(sdp->sd_name), sdp->sd_file->ifl_name,
505 			    MSG_INTL(MSG_MAP_DIFF_SYMMUL));
506 			return (FALSE);
507 		}
508 	}
509 
510 	/*
511 	 * Assign the symbol to the segment.
512 	 */
513 	if (aplist_append(&sgp->sg_sizesym, sdp, AL_CNT_SG_SIZESYM) == NULL)
514 		return (FALSE);
515 
516 	return (TRUE);
517 }
518 
519 /*
520  * Allocate a zeroed segment descriptor.
521  *
522  * exit:
523  *	Returns pointer to the descriptor on success, NULL on failure.
524  *	The contents of the returned descriptor have been zeroed.
525  *	The returned descriptor is not added to the segment list
526  *	(ofl_segs). That is done using ld_map_seg_insert().
527  */
528 Sg_desc *
529 ld_map_seg_alloc(const char *name, Word p_type, sg_flags_t sg_flags)
530 {
531 	Sg_desc	*sgp;
532 
533 	if ((sgp = libld_calloc(sizeof (Sg_desc), 1)) == NULL)
534 		return (NULL);
535 	sgp->sg_phdr.p_type = p_type;
536 	sgp->sg_name = name;
537 	sgp->sg_flags = sg_flags;
538 
539 	return (sgp);
540 }
541 
542 /*
543  * Return the PT_SUNWSTACK segment descriptor from the ofl_segs list.
544  * This segment is part of the default set and cannot be removed, so
545  * this routine will always succeed.
546  *
547  * exit:
548  *	The descriptor is located, a DBG_STATE_MOD_BEFORE debug
549  *	message issued, the FLG_SG_DISABLED flag is cleared, and the
550  *	descriptor pointer returned.
551  */
552 Sg_desc *
553 ld_map_seg_stack(Mapfile *mf)
554 {
555 	Ofl_desc	*ofl = mf->mf_ofl;
556 	Sg_desc		*sgp;
557 	Aliste		idx;
558 
559 	/*
560 	 * The stack is established by exec(), using the executable's program
561 	 * headers, before any sharable objects are loaded. If there is a
562 	 * PT_SUNWSTACK program header, exec() will act on it. As such, stack
563 	 * program headers are normally only applicable to executables.
564 	 *
565 	 * However, ELF allows a sharable object with an interpreter to
566 	 * be executed directly, and in this extremely rare case, the
567 	 * PT_SUNWSTACK program header would have meaning. Rather than
568 	 * second guess user intent, we simply create it on demand for any
569 	 * dynamic object, trusting that the user has a good reason for it.
570 	 */
571 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp))
572 		if (sgp->sg_phdr.p_type == PT_SUNWSTACK) {
573 			DBG_CALL(Dbg_map_seg(mf->mf_ofl, DBG_STATE_MOD_BEFORE,
574 			    idx, sgp, mf->mf_lineno));
575 			sgp->sg_flags &= ~FLG_SG_DISABLED;
576 			return (sgp);
577 		}
578 
579 	/*NOTREACHED*/
580 	return (NULL);
581 }
582 
583 /*
584  * Finish the initialization of a new segment descriptor allocated by
585  * ld_map_seg_alloc(), and enter it into the segment list.
586  *
587  * entry:
588  *	mf - Mapfile descriptor
589  *	seg_type - One of DBG_SEG_NEW or DBG_SEG_NEW_IMPLICIT
590  *	ins_head - If TRUE, the new segment goes at the front of
591  *		others of its type. If FALSE, it goes at the end.
592  *	sgp - Segment descriptor to enter.
593  *	where - Insertion point, initialized by a previous (failed) call to
594  *		ld_seg_lookup(). Ignored if the segment has a NULL sg_name.
595  *
596  * exit:
597  *	On success, returns SEG_INS_OK. A non-fatal error is indicated with
598  *	a return value of SEG_INS_SKIP, in which case the descriptor is
599  *	not entered, but the user is expected to discard it and continue
600  *	running. On failure, returns SEG_INS_FAIL.
601  *
602  * note:
603  *	This routine will modify the contents of the descriptor referenced
604  *	by sgp_tmpl before allocating the new descriptor. The caller must
605  *	not expect it to be unmodified.
606  */
607 ld_map_seg_ins_t
608 ld_map_seg_insert(Mapfile *mf, dbg_state_t dbg_state, Sg_desc *sgp,
609     avl_index_t where)
610 {
611 	Ofl_desc	*ofl = mf->mf_ofl;
612 	Aliste		idx;
613 	Sg_desc		*sgp2;		/* temp segment descriptor pointer */
614 	int		ins_head;
615 	Xword		sg_ndx;
616 
617 	/*
618 	 * If specific fields have not been supplied via
619 	 * map_equal(), make sure defaults are supplied.
620 	 */
621 	if (((sgp->sg_flags & FLG_SG_P_TYPE) == 0) &&
622 	    (sgp->sg_phdr.p_type == PT_NULL)) {
623 		/*
624 		 * Default to a loadable segment.
625 		 */
626 		sgp->sg_phdr.p_type = PT_LOAD;
627 		sgp->sg_flags |= FLG_SG_P_TYPE;
628 	}
629 	if (sgp->sg_phdr.p_type == PT_LOAD) {
630 		if ((sgp->sg_flags & FLG_SG_P_FLAGS) == 0) {
631 			/*
632 			 * Default to read/write and execute.
633 			 */
634 			sgp->sg_phdr.p_flags = PF_R + PF_W + PF_X;
635 			sgp->sg_flags |= FLG_SG_P_FLAGS;
636 		}
637 		if ((sgp->sg_flags & FLG_SG_P_ALIGN) == 0) {
638 			/*
639 			 * Default to segment alignment
640 			 */
641 			sgp->sg_phdr.p_align = ld_targ.t_m.m_segm_align;
642 			sgp->sg_flags |= FLG_SG_P_ALIGN;
643 		}
644 	}
645 
646 	/*
647 	 * Determine where the new item should be inserted in
648 	 * the segment descriptor list.
649 	 */
650 	switch (sgp->sg_phdr.p_type) {
651 	case PT_LOAD:
652 		if (sgp->sg_flags & FLG_SG_EMPTY)
653 			sgp->sg_id = SGID_TEXT_EMPTY;
654 		else
655 			sgp->sg_id = SGID_TEXT;
656 		break;
657 	case PT_NULL:
658 		if (sgp->sg_flags & FLG_SG_EMPTY)
659 			sgp->sg_id = SGID_NULL_EMPTY;
660 		else
661 			sgp->sg_id = SGID_NULL;
662 		break;
663 	case PT_NOTE:
664 		sgp->sg_id = SGID_NOTE;
665 		break;
666 	default:
667 		mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGTYP),
668 		    EC_WORD(sgp->sg_phdr.p_type));
669 		return (SEG_INS_FAIL);
670 	}
671 
672 	/*
673 	 * Add the descriptor to the segment list. In the v1 syntax,
674 	 * new sections are added at the head of their type, while in
675 	 * the newer syntax, they go at the end of their type.
676 	 */
677 	sg_ndx = 0;
678 	ins_head = (mf->mf_version == MFV_SYSV);
679 	for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) {
680 		if (ins_head) {	/* Insert before the others of its type */
681 			if (sgp->sg_id > sgp2->sg_id) {
682 				sg_ndx++;
683 				continue;
684 			}
685 		} else {	/* Insert after the others of its type */
686 			if (sgp->sg_id >= sgp2->sg_id) {
687 				sg_ndx++;
688 				continue;
689 			}
690 		}
691 		break;
692 	}
693 	if (aplist_insert(&ofl->ofl_segs, sgp, AL_CNT_SEGMENTS, idx) == NULL)
694 		return (SEG_INS_FAIL);
695 	if (sgp->sg_name != NULL)
696 		avl_insert(&ofl->ofl_segs_avl, sgp, where);
697 
698 	DBG_CALL(Dbg_map_seg(ofl, dbg_state, sg_ndx, sgp, mf->mf_lineno));
699 	return (SEG_INS_OK);
700 }
701 
702 /*
703  * Add an entrance criteria record for the specified segment
704  *
705  * entry:
706  *	mf - Mapfile descriptor
707  *	sgp - Segment for which a new entrance criteria record is needed
708  *	name - NULL, or name by which the entrance criteria can be referenced.
709  *
710  * exit:
711  *	On success, a pointer to the new entrace criteria record is
712  *	returned, the contents of which have been zeroed. On failure,
713  *	NULL is returned.
714  */
715 Ent_desc *
716 ld_map_seg_ent_add(Mapfile *mf, Sg_desc *sgp, const char *name)
717 {
718 	Ent_desc	*enp;
719 	avl_index_t	where;
720 	Ofl_desc	*ofl = mf->mf_ofl;
721 
722 	if ((name != NULL) &&
723 	    (ld_ent_lookup(mf->mf_ofl, name, &where) != NULL)) {
724 		mf_fatal(mf, MSG_INTL(MSG_MAP_DUPNAMENT), name);
725 		return (NULL);
726 	}
727 
728 	/* Allocate and initialize the entrace criteria descriptor */
729 	if ((enp = libld_calloc(1, sizeof (*enp))) == NULL)
730 		return (NULL);
731 	enp->ec_name = name;
732 	enp->ec_segment = sgp;	 /* Tie criteria to segment */
733 
734 
735 	/*
736 	 * Insert into the APlist. The mf_ec_insndx field for each mapfile
737 	 * starts at 0, and is incremented with each insertion. This means
738 	 * that the entrance criteria for each mapfile go to the head of
739 	 * the list, but that within a single mapfile, they are inserted in
740 	 * the order they are seen.
741 	 */
742 	if (aplist_insert(&ofl->ofl_ents, enp, AL_CNT_OFL_ENTRANCE,
743 	    mf->mf_ec_insndx) == NULL)
744 		return (NULL);
745 	mf->mf_ec_insndx++;
746 
747 	/*
748 	 * If the entrance criteria is named insert it into the AVL tree
749 	 * as well. This provides O(logN) lookups by name.
750 	 */
751 	if (name != NULL)
752 		avl_insert(&ofl->ofl_ents_avl, enp, where);
753 
754 	return (enp);
755 }
756 
757 Boolean
758 ld_map_seg_ent_files(Mapfile *mf, Ent_desc *enp, Word ecf_type, const char *str)
759 {
760 	Ent_desc_file	edf;
761 
762 	/*
763 	 * The v1 sysv syntax can let an empty string get in, consisting of
764 	 * just a '*' where the '*' is interpreted as 'basename'.
765 	 */
766 	if (str[0] == '\0') {
767 		mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM));
768 		return (FALSE);
769 	}
770 
771 	/* Basename or objname string must not contain a path separator (/) */
772 	if ((ecf_type != TYP_ECF_PATH) && (strchr(str, '/') != NULL)) {
773 		const char *msg = (ecf_type == TYP_ECF_BASENAME) ?
774 		    MSG_INTL(MSG_MAP_BADBNAME) : MSG_INTL(MSG_MAP_BADONAME);
775 
776 		mf_fatal(mf, msg, str);
777 		return (FALSE);
778 	}
779 
780 	edf.edf_flags = ecf_type;
781 	edf.edf_name = str;
782 	edf.edf_name_len = strlen(edf.edf_name);
783 
784 	/* Does it have an archive member suffix? */
785 	if ((edf.edf_name[edf.edf_name_len - 1] == ')') &&
786 	    (strrchr(edf.edf_name, '(') != NULL))
787 		edf.edf_flags |= FLG_ECF_ARMEMBER;
788 
789 	if (alist_append(&enp->ec_files, &edf, sizeof (edf),
790 	    AL_CNT_EC_FILES) == NULL)
791 		return (FALSE);
792 
793 	/*
794 	 * Note that an entrance criteria requiring file name matching exists
795 	 * in the system. This is used by ld_place_path_info_init() to
796 	 * skip Place_pathinfo initialization in cases where there are
797 	 * no entrance criteria that will use the results.
798 	 */
799 	mf->mf_ofl->ofl_flags |= FLG_OF_EC_FILES;
800 
801 	return (TRUE);
802 }
803 
804 /*
805  * Prepare an ld_map_ver_t structure for a new mapfile defined version.
806  *
807  * exit:
808  *	Returns TRUE for success, FALSE for failure.
809  */
810 Boolean
811 ld_map_sym_ver_init(Mapfile *mf, char *name, ld_map_ver_t *mv)
812 {
813 	Word		hash;
814 	Ofl_desc	*ofl = mf->mf_ofl;
815 
816 	mv->mv_name = name;
817 	mv->mv_scope = FLG_SCOPE_DFLT;
818 	mv->mv_errcnt = 0;
819 
820 	/*
821 	 * If we're generating segments within the image then any symbol
822 	 * reductions will be processed (ie. applied to relocations and symbol
823 	 * table entries).  Otherwise (when creating a relocatable object) any
824 	 * versioning information is simply recorded for use in a later
825 	 * (segment generating) link-edit.
826 	 */
827 	if (ofl->ofl_flags & FLG_OF_RELOBJ)
828 		ofl->ofl_flags |= FLG_OF_VERDEF;
829 
830 	/*
831 	 * If no version descriptors have yet been set up, initialize a base
832 	 * version to represent the output file itself.  This `base' version
833 	 * catches any internally generated symbols (_end, _etext, etc.) and
834 	 * serves to initialize the output version descriptor count.
835 	 */
836 	if (ofl->ofl_vercnt == 0) {
837 		if (ld_vers_base(ofl) == (Ver_desc *)S_ERROR)
838 			return (FALSE);
839 	}
840 
841 	/*
842 	 * If this definition has an associated version name then generate a
843 	 * new version descriptor and an associated version symbol index table.
844 	 */
845 	if (name) {
846 		ofl->ofl_flags |= FLG_OF_VERDEF;
847 
848 		/*
849 		 * Traverse the present version descriptor list to see if there
850 		 * is already one of the same name, otherwise create a new one.
851 		 */
852 		/* LINTED */
853 		hash = (Word)elf_hash(name);
854 		if (((mv->mv_vdp = ld_vers_find(name, hash,
855 		    ofl->ofl_verdesc)) == NULL) &&
856 		    ((mv->mv_vdp = ld_vers_desc(name, hash,
857 		    &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
858 			return (FALSE);
859 
860 		/*
861 		 * Initialize any new version with an index, the file from
862 		 * which it was first referenced, and a WEAK flag (indicates
863 		 * that there are no symbols assigned to it yet).
864 		 */
865 		if (mv->mv_vdp->vd_ndx == 0) {
866 			/* LINTED */
867 			mv->mv_vdp->vd_ndx = (Half)++ofl->ofl_vercnt;
868 			mv->mv_vdp->vd_file = ld_map_ifl(mf);
869 			mv->mv_vdp->vd_flags = VER_FLG_WEAK;
870 		}
871 	} else {
872 		/*
873 		 * If a version definition hasn't been specified assign any
874 		 * symbols to the base version.
875 		 */
876 		mv->mv_vdp = (Ver_desc *)ofl->ofl_verdesc->apl_data[0];
877 	}
878 
879 	return (TRUE);
880 }
881 
882 /*
883  * Change the current scope for the given version.
884  *
885  * entry:
886  *	mf - Mapfile descriptor
887  *	scope_name - Name for new scope
888  *	mv - Information related to version being defined
889  *
890  * exit:
891  *	On success, mv is updated to change the current scope.
892  *	On failure, mv->errcnt is incremented, and mv is otherwise unaltered.
893  */
894 void
895 ld_map_sym_scope(Mapfile *mf, const char *scope_name, ld_map_ver_t *mv)
896 {
897 	typedef struct {
898 		const char	*name;		/* scope keyword string */
899 		ld_map_scope_t	type;		/* Resulting type */
900 		ofl_flag_t	ofl_flags;	/* 0, or ofl flags to add */
901 	} scope_t;
902 
903 	/*
904 	 * Valid symbol scope keywords
905 	 *
906 	 * All symbols added by a mapfile are actually global entries, and
907 	 * are assigned the scope that is presently in effect.
908 	 *
909 	 * If a protected/symbolic scope is detected, remember this. If
910 	 * a protected/symbolic scope is the only scope defined in this
911 	 * (or any other mapfiles), then the mode -Bsymbolic is established.
912 	 */
913 	static scope_t scope_list[] = {
914 		{ MSG_ORIG(MSG_MAPKW_DEFAULT), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
915 		{ MSG_ORIG(MSG_MAPKW_ELIMINATE), FLG_SCOPE_ELIM, 0 },
916 		{ MSG_ORIG(MSG_MAPKW_EXPORTED), FLG_SCOPE_EXPT, 0 },
917 		{ MSG_ORIG(MSG_MAPKW_HIDDEN), FLG_SCOPE_HIDD, 0 },
918 		{ MSG_ORIG(MSG_MAPKW_GLOBAL), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
919 		{ MSG_ORIG(MSG_MAPKW_LOCAL), FLG_SCOPE_HIDD, 0 },
920 		{ MSG_ORIG(MSG_MAPKW_PROTECTED),
921 		    FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
922 		{ MSG_ORIG(MSG_MAPKW_SINGLETON),
923 		    FLG_SCOPE_SNGL, FLG_OF_MAPGLOB },
924 		{ MSG_ORIG(MSG_MAPKW_SYMBOLIC),
925 		    FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
926 
927 		/* List must be null terminated */
928 		{ 0 }
929 	};
930 
931 	/*
932 	 * Size of buffer needed to format the names in scope_list[]. Must
933 	 * be kept in sync with scope_list.
934 	 */
935 	static size_t scope_list_bufsize =
936 	    KW_NAME_SIZE(MSG_MAPKW_DEFAULT) +
937 	    KW_NAME_SIZE(MSG_MAPKW_ELIMINATE) +
938 	    KW_NAME_SIZE(MSG_MAPKW_EXPORTED) +
939 	    KW_NAME_SIZE(MSG_MAPKW_HIDDEN) +
940 	    KW_NAME_SIZE(MSG_MAPKW_GLOBAL) +
941 	    KW_NAME_SIZE(MSG_MAPKW_LOCAL) +
942 	    KW_NAME_SIZE(MSG_MAPKW_PROTECTED) +
943 	    KW_NAME_SIZE(MSG_MAPKW_SINGLETON) +
944 	    KW_NAME_SIZE(MSG_MAPKW_SYMBOLIC);
945 
946 	scope_t	*scope;
947 
948 	scope = ld_map_kwfind(scope_name, scope_list,
949 	    SGSOFFSETOF(scope_t, name), sizeof (scope_list[0]));
950 	if (scope == NULL) {
951 		char buf[VLA_SIZE(scope_list_bufsize)];
952 
953 		mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMSCOPE),
954 		    ld_map_kwnames(scope_list, SGSOFFSETOF(scope_t, name),
955 		    sizeof (scope[0]), buf, scope_list_bufsize), scope_name);
956 		mv->mv_errcnt++;
957 		return;
958 	}
959 
960 	mv->mv_scope = scope->type;
961 	mf->mf_ofl->ofl_flags |= scope->ofl_flags;
962 }
963 
964 /*
965  * Process the special auto-reduction directive ('*'). It can be specified
966  * in hidden/local, and eliminate scope. This directive indicates that all
967  * symbols processed that are not explicitly defined to be global are to be
968  * reduced to hidden/local scope in, or eliminated from, the output image.
969  *
970  * An auto-reduction directive also implies that a version definition must
971  * be created, as the user has effectively defined an interface.
972  */
973 void
974 ld_map_sym_autoreduce(Mapfile *mf, ld_map_ver_t *mv)
975 {
976 	switch (mv->mv_scope) {
977 	case FLG_SCOPE_HIDD:
978 		mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOLCL);
979 		break;
980 	case FLG_SCOPE_ELIM:
981 		mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOELM);
982 		break;
983 	default:
984 		/*
985 		 * Auto reduction has been applied to a scope that doesn't
986 		 * support it. This should be a fatal error, but we limit
987 		 * it to a warning for version 1 mapfiles. For years, we
988 		 * quietly ignored this case, so there may be mapfiles in
989 		 * production use that we do not wish to break.
990 		 */
991 		if (mf->mf_version == 1) {
992 			mf_warn0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
993 		} else {
994 			mf_fatal0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
995 			mv->mv_errcnt++;
996 		}
997 	}
998 }
999 
1000 /*
1001  * Add a standard or auxiliary filter to the given symbol
1002  *
1003  * entry:
1004  *	mf - Mapfile descriptor
1005  *	mv - Information related to version being defined
1006  *	ms - Information related to symbol being defined
1007  *	dft_flag - One of FLG_SY_STDFLTR or FLG_SY_AUXFLTR,
1008  *		specifying the type of filter.
1009  *	filtee - String giving filtee to be added
1010  *
1011  * exit:
1012  *	On success, the filtee is added. On failure, mv->errcnt is
1013  *	incremented, and mv/ms are otherwise unaltered.
1014  */
1015 void
1016 ld_map_sym_filtee(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms,
1017     Word dft_flag, const char *filtee)
1018 {
1019 	/*
1020 	 * A given symbol can only be tied to a single filter, be it
1021 	 * a standard filter, or auxiliary.
1022 	 */
1023 	if (ms->ms_filtee) {
1024 		mf_fatal0(mf, MSG_INTL(MSG_MAP_MULTFILTEE));
1025 		mv->mv_errcnt++;
1026 		return;
1027 	}
1028 
1029 	/* Symbol filtering is only for sharable objects */
1030 	if (!(mf->mf_ofl->ofl_flags & FLG_OF_SHAROBJ)) {
1031 		mf_fatal0(mf, MSG_INTL(MSG_MAP_FLTR_ONLYAVL));
1032 		mv->mv_errcnt++;
1033 		return;
1034 	}
1035 
1036 	ms->ms_filtee = filtee;
1037 	ms->ms_dft_flag = dft_flag;
1038 	ms->ms_sdflags |= dft_flag;
1039 	mf->mf_ofl->ofl_flags |= FLG_OF_SYMINFO;
1040 }
1041 
1042 /*
1043  * Enter a mapfile defined symbol into the given version
1044  *
1045  * entry:
1046  *	mf - Mapfile descriptor
1047  *	ms - Information related to symbol being added to version
1048  *
1049  * exit:
1050  *	On success, returns TRUE. On failure that requires an immediate
1051  *	halt, returns FALSE.
1052  *
1053  *	On failure that requires eventual halt, but for which it would
1054  *	be OK to continue parsing in hopes of flushing out additional
1055  *	problems, increments mv->mv_errcnt, and returns TRUE.
1056  */
1057 Boolean
1058 ld_map_sym_enter(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms)
1059 {
1060 	Ofl_desc	*ofl = mf->mf_ofl;
1061 	Word		hash;
1062 	avl_index_t	where;
1063 	Sym		*sym;
1064 	Sym_desc	*sdp;
1065 	const char	*conflict;
1066 
1067 	/*
1068 	 * Add the new symbol.  It should be noted that all
1069 	 * symbols added by the mapfile start out with global
1070 	 * scope, thus they will fall through the normal symbol
1071 	 * resolution process.  Symbols defined as locals will
1072 	 * be reduced in scope after all input file processing.
1073 	 */
1074 	/* LINTED */
1075 	hash = (Word)elf_hash(ms->ms_name);
1076 	DBG_CALL(Dbg_map_version(ofl->ofl_lml, mv->mv_name, ms->ms_name,
1077 	    mv->mv_scope));
1078 	if ((sdp = ld_sym_find(ms->ms_name, hash, &where, ofl)) == NULL) {
1079 		if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
1080 			return (FALSE);
1081 
1082 		/*
1083 		 * Make sure any parent or external declarations
1084 		 * fall back to references.
1085 		 */
1086 		if (ms->ms_sdflags & (FLG_SY_PARENT | FLG_SY_EXTERN)) {
1087 			/*
1088 			 * Turn it into a reference by setting
1089 			 * the section index to UNDEF.
1090 			 */
1091 			sym->st_shndx = ms->ms_shndx = SHN_UNDEF;
1092 
1093 			/*
1094 			 * It is wrong to specify size or value for an
1095 			 * external symbol.
1096 			 */
1097 			if (ms->ms_value_set || (ms->ms_size != 0)) {
1098 				mf_fatal0(mf, MSG_INTL(MSG_MAP_NOEXVLSZ));
1099 				mv->mv_errcnt++;
1100 				return (TRUE);
1101 			}
1102 		} else {
1103 			sym->st_shndx = (Half)ms->ms_shndx;
1104 		}
1105 
1106 		sym->st_value = ms->ms_value;
1107 		sym->st_size = ms->ms_size;
1108 		sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1109 
1110 		if ((sdp = ld_sym_enter(ms->ms_name, sym, hash,
1111 		    ld_map_ifl(mf), ofl, 0, ms->ms_shndx, ms->ms_sdflags,
1112 		    &where)) == (Sym_desc *)S_ERROR)
1113 			return (FALSE);
1114 
1115 		sdp->sd_flags &= ~FLG_SY_CLEAN;
1116 
1117 		/*
1118 		 * Identify any references.  FLG_SY_MAPREF is
1119 		 * turned off once a relocatable object with
1120 		 * the same symbol is found, thus the existence
1121 		 * of FLG_SY_MAPREF at symbol validation is
1122 		 * used to flag undefined/misspelled entries.
1123 		 */
1124 		if (sym->st_shndx == SHN_UNDEF)
1125 			sdp->sd_flags |= (FLG_SY_MAPREF | FLG_SY_GLOBREF);
1126 
1127 	} else {
1128 		conflict = NULL;
1129 		sym = sdp->sd_sym;
1130 
1131 		/*
1132 		 * If this symbol already exists, make sure this
1133 		 * definition doesn't conflict with the former.
1134 		 * Provided it doesn't, multiple definitions
1135 		 * from different mapfiles can augment each
1136 		 * other.
1137 		 */
1138 		/* BEGIN CSTYLED */
1139 		if (sym->st_value) {
1140 			if (ms->ms_value && (sym->st_value != ms->ms_value))
1141 				conflict = MSG_INTL(MSG_MAP_DIFF_SYMVAL);
1142 		} else {
1143 			sym->st_value = ms->ms_value;
1144 		}
1145 		if (sym->st_size) {
1146 			if (ms->ms_size && (sym->st_size != ms->ms_size))
1147 				conflict = MSG_INTL(MSG_MAP_DIFF_SYMSZ);
1148 		} else {
1149 			sym->st_size = ms->ms_size;
1150 		}
1151 		if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) {
1152 			if ((ms->ms_type != STT_NOTYPE) &&
1153 			    (ELF_ST_TYPE(sym->st_info) != ms->ms_type))
1154 				conflict = MSG_INTL(MSG_MAP_DIFF_SYMTYP);
1155 		} else {
1156 			sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1157 		}
1158 		if (sym->st_shndx != SHN_UNDEF) {
1159 			if ((ms->ms_shndx != SHN_UNDEF) &&
1160 			    (sym->st_shndx != ms->ms_shndx))
1161 				conflict = MSG_INTL(MSG_MAP_DIFF_SYMNDX);
1162 		} else {
1163 			sym->st_shndx = sdp->sd_shndx = ms->ms_shndx;
1164 		}
1165 		/* END CSTYLED */
1166 
1167 		if ((sdp->sd_flags & MSK_SY_GLOBAL) &&
1168 		    (sdp->sd_aux->sa_overndx != VER_NDX_GLOBAL) &&
1169 		    (mv->mv_vdp->vd_ndx != VER_NDX_GLOBAL) &&
1170 		    (sdp->sd_aux->sa_overndx != mv->mv_vdp->vd_ndx)) {
1171 			conflict = MSG_INTL(MSG_MAP_DIFF_SYMVER);
1172 		}
1173 
1174 		if (conflict) {
1175 			mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1176 			    demangle(ms->ms_name),
1177 			    sdp->sd_file->ifl_name, conflict);
1178 			mv->mv_errcnt++;
1179 			return (TRUE);
1180 		}
1181 
1182 		/*
1183 		 * If this mapfile entry supplies a definition,
1184 		 * indicate that the symbol is now used.
1185 		 */
1186 		if (ms->ms_shndx != SHN_UNDEF)
1187 			sdp->sd_flags |= FLG_SY_MAPUSED;
1188 	}
1189 
1190 	/*
1191 	 * A symbol declaration that defines a size but no
1192 	 * value is processed as a request to create an
1193 	 * associated backing section.  The intent behind this
1194 	 * functionality is to provide OBJT definitions within
1195 	 * filters that are not ABS.  ABS symbols don't allow
1196 	 * copy-relocations to be established to filter OBJT
1197 	 * definitions.
1198 	 */
1199 	if ((ms->ms_shndx == SHN_ABS) && ms->ms_size && !ms->ms_value_set) {
1200 		/* Create backing section if not there */
1201 		if (sdp->sd_isc == NULL) {
1202 			Is_desc	*isp;
1203 
1204 			if (ms->ms_type == STT_OBJECT) {
1205 				if ((isp = ld_make_data(ofl, ms->ms_size)) ==
1206 				    (Is_desc *)S_ERROR)
1207 					return (FALSE);
1208 			} else {
1209 				if ((isp = ld_make_text(ofl, ms->ms_size)) ==
1210 				    (Is_desc *)S_ERROR)
1211 					return (FALSE);
1212 			}
1213 
1214 			sdp->sd_isc = isp;
1215 			isp->is_file = ld_map_ifl(mf);
1216 		}
1217 
1218 		/*
1219 		 * Now that backing storage has been created,
1220 		 * associate the symbol descriptor.  Remove the
1221 		 * symbols special section tag so that it will
1222 		 * be assigned the correct section index as part
1223 		 * of update symbol processing.
1224 		 */
1225 		sdp->sd_flags &= ~FLG_SY_SPECSEC;
1226 		ms->ms_sdflags &= ~FLG_SY_SPECSEC;
1227 	}
1228 
1229 	/*
1230 	 * Indicate the new symbols scope.  Although the
1231 	 * symbols st_other field will eventually be updated as
1232 	 * part of writing out the final symbol, update the
1233 	 * st_other field here to trigger better diagnostics
1234 	 * during symbol validation (for example, undefined
1235 	 * references that are defined symbolic in a mapfile).
1236 	 */
1237 	if (mv->mv_scope == FLG_SCOPE_HIDD) {
1238 		/*
1239 		 * This symbol needs to be reduced to local.
1240 		 */
1241 		if (ofl->ofl_flags & FLG_OF_REDLSYM) {
1242 			sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1243 			sdp->sd_sym->st_other = STV_ELIMINATE;
1244 		} else {
1245 			sdp->sd_flags |= FLG_SY_HIDDEN;
1246 			sdp->sd_sym->st_other = STV_HIDDEN;
1247 		}
1248 	} else if (mv->mv_scope == FLG_SCOPE_ELIM) {
1249 		/*
1250 		 * This symbol needs to be eliminated.  Note,
1251 		 * the symbol is also tagged as local to trigger
1252 		 * any necessary relocation processing prior
1253 		 * to the symbol being eliminated.
1254 		 */
1255 		sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1256 		sdp->sd_sym->st_other = STV_ELIMINATE;
1257 
1258 	} else {
1259 		/*
1260 		 * This symbol is explicitly defined to remain
1261 		 * global.
1262 		 */
1263 		sdp->sd_flags |= ms->ms_sdflags;
1264 
1265 		/*
1266 		 * Qualify any global scope.
1267 		 */
1268 		if (mv->mv_scope == FLG_SCOPE_SNGL) {
1269 			sdp->sd_flags |= (FLG_SY_SINGLE | FLG_SY_NDIR);
1270 			sdp->sd_sym->st_other = STV_SINGLETON;
1271 		} else if (mv->mv_scope == FLG_SCOPE_PROT) {
1272 			sdp->sd_flags |= FLG_SY_PROTECT;
1273 			sdp->sd_sym->st_other = STV_PROTECTED;
1274 		} else if (mv->mv_scope == FLG_SCOPE_EXPT) {
1275 			sdp->sd_flags |= FLG_SY_EXPORT;
1276 			sdp->sd_sym->st_other = STV_EXPORTED;
1277 		} else
1278 			sdp->sd_flags |= FLG_SY_DEFAULT;
1279 
1280 		/*
1281 		 * Record the present version index for later
1282 		 * potential versioning.
1283 		 */
1284 		if ((sdp->sd_aux->sa_overndx == 0) ||
1285 		    (sdp->sd_aux->sa_overndx == VER_NDX_GLOBAL))
1286 			sdp->sd_aux->sa_overndx = mv->mv_vdp->vd_ndx;
1287 		mv->mv_vdp->vd_flags |= FLG_VER_REFER;
1288 	}
1289 
1290 	conflict = NULL;
1291 
1292 	/*
1293 	 * Carry out some validity checks to ensure incompatible
1294 	 * symbol characteristics have not been defined.
1295 	 * These checks are carried out after symbols are added
1296 	 * or resolved, to catch single instance, and
1297 	 * multi-instance definition inconsistencies.
1298 	 */
1299 	if ((sdp->sd_flags & (FLG_SY_HIDDEN | FLG_SY_ELIM)) &&
1300 	    ((mv->mv_scope != FLG_SCOPE_HIDD) &&
1301 	    (mv->mv_scope != FLG_SCOPE_ELIM))) {
1302 		conflict = MSG_INTL(MSG_MAP_DIFF_SYMLCL);
1303 
1304 	} else if ((sdp->sd_flags &
1305 	    (FLG_SY_SINGLE | FLG_SY_EXPORT)) &&
1306 	    ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1307 	    (mv->mv_scope != FLG_SCOPE_EXPT) &&
1308 	    (mv->mv_scope != FLG_SCOPE_SNGL))) {
1309 		conflict = MSG_INTL(MSG_MAP_DIFF_SYMGLOB);
1310 
1311 	} else if ((sdp->sd_flags & FLG_SY_PROTECT) &&
1312 	    ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1313 	    (mv->mv_scope != FLG_SCOPE_PROT))) {
1314 		conflict = MSG_INTL(MSG_MAP_DIFF_SYMPROT);
1315 
1316 	} else if ((sdp->sd_flags & FLG_SY_NDIR) &&
1317 	    (mv->mv_scope == FLG_SCOPE_PROT)) {
1318 		conflict = MSG_INTL(MSG_MAP_DIFF_PROTNDIR);
1319 
1320 	} else if ((sdp->sd_flags & FLG_SY_DIR) &&
1321 	    (mv->mv_scope == FLG_SCOPE_SNGL)) {
1322 		conflict = MSG_INTL(MSG_MAP_DIFF_SNGLDIR);
1323 	}
1324 
1325 	if (conflict) {
1326 		/*
1327 		 * Select the conflict message from either a
1328 		 * single instance or multi-instance definition.
1329 		 */
1330 		if (sdp->sd_file->ifl_name == mf->mf_name) {
1331 			mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF2),
1332 			    demangle(ms->ms_name), conflict);
1333 		} else {
1334 			mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1335 			    demangle(ms->ms_name),
1336 			    sdp->sd_file->ifl_name, conflict);
1337 		}
1338 		mv->mv_errcnt++;
1339 		return (TRUE);
1340 	}
1341 
1342 	/*
1343 	 * Indicate that this symbol has been explicitly
1344 	 * contributed from a mapfile.
1345 	 */
1346 	sdp->sd_flags |= (FLG_SY_MAPFILE | FLG_SY_EXPDEF);
1347 
1348 	/*
1349 	 * If we've encountered a symbol definition simulate
1350 	 * that an input file has been processed - this allows
1351 	 * things like filters to be created purely from a
1352 	 * mapfile.
1353 	 */
1354 	if (ms->ms_type != STT_NOTYPE)
1355 		ofl->ofl_objscnt++;
1356 	DBG_CALL(Dbg_map_symbol(ofl, sdp));
1357 
1358 	/*
1359 	 * If this symbol has an associated filtee, record the
1360 	 * filtee string and associate the string index with the
1361 	 * symbol.  This is used later to associate the syminfo
1362 	 * information with the necessary .dynamic entry.
1363 	 */
1364 	if (ms->ms_filtee) {
1365 		Dfltr_desc *	dftp;
1366 		Sfltr_desc	sft;
1367 		Aliste		idx, _idx, nitems;
1368 
1369 		/*
1370 		 * Make sure we don't duplicate any filtee
1371 		 * strings, and create a new descriptor if
1372 		 * necessary.
1373 		 */
1374 		idx = nitems = alist_nitems(ofl->ofl_dtsfltrs);
1375 		for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx, dftp)) {
1376 			if ((ms->ms_dft_flag != dftp->dft_flag) ||
1377 			    (strcmp(dftp->dft_str, ms->ms_filtee)))
1378 				continue;
1379 			idx = _idx;
1380 			break;
1381 		}
1382 		if (idx == nitems) {
1383 			Dfltr_desc	dft;
1384 
1385 			dft.dft_str = ms->ms_filtee;
1386 			dft.dft_flag = ms->ms_dft_flag;
1387 			dft.dft_ndx = 0;
1388 
1389 			/*
1390 			 * The following append puts the new
1391 			 * item at the offset contained in
1392 			 * idx, because we know idx contains
1393 			 * the index of the next available slot.
1394 			 */
1395 			if (alist_append(&ofl->ofl_dtsfltrs, &dft,
1396 			    sizeof (Dfltr_desc), AL_CNT_OFL_DTSFLTRS) == NULL)
1397 				return (FALSE);
1398 		}
1399 
1400 		/*
1401 		 * Create a new filter descriptor for this
1402 		 * symbol.
1403 		 */
1404 		sft.sft_sdp = sdp;
1405 		sft.sft_idx = idx;
1406 
1407 		if (alist_append(&ofl->ofl_symfltrs, &sft, sizeof (Sfltr_desc),
1408 		    AL_CNT_OFL_SYMFLTRS) == NULL)
1409 			return (FALSE);
1410 	}
1411 
1412 	return (TRUE);
1413 }
1414 
1415 /*
1416  * In both the version 1 and version 2 syntaxes, a version definition
1417  * can have 0 or more inherited versions following the closing '}',
1418  * terminated by a ';'.
1419  *
1420  * Add the inherited names, and return when the terminator is seen.
1421  */
1422 Boolean
1423 ld_map_sym_ver_fini(Mapfile *mf, ld_map_ver_t *mv)
1424 {
1425 	Token		tok;
1426 	ld_map_tkval_t	tkv;		/* Value of token */
1427 	Boolean		done = FALSE;
1428 	Conv_inv_buf_t	inv_buf;
1429 	const char	*name;
1430 	Ver_desc	*vdp;
1431 	Word		hash;
1432 
1433 	/*
1434 	 * Read version names until we encounter the ';' terminator.
1435 	 */
1436 	while (!done) {
1437 		switch (tok = ld_map_gettoken(mf, 0, &tkv)) {
1438 		case TK_ERROR:
1439 			return (FALSE);
1440 
1441 		case TK_STRING:
1442 			name = tkv.tkv_str;
1443 
1444 			/* The unnamed global scope can't inherit */
1445 			if (mv->mv_vdp->vd_ndx == VER_NDX_GLOBAL) {
1446 				mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXINHERIT),
1447 				    name);
1448 				return (FALSE);
1449 			}
1450 
1451 			/*
1452 			 * Generate a new version descriptor if it doesn't
1453 			 * already exist.
1454 			 */
1455 			/* LINTED */
1456 			hash = (Word)elf_hash(name);
1457 			vdp = ld_vers_find(name, hash, mf->mf_ofl->ofl_verdesc);
1458 			if ((vdp == NULL) && ((vdp = ld_vers_desc(name, hash,
1459 			    &mf->mf_ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
1460 				return (FALSE);
1461 
1462 			/*
1463 			 * Add the new version descriptor to the parent version
1464 			 * descriptors reference list.  Indicate the version
1465 			 * descriptors first reference (used for error diags
1466 			 * if undefined version dependencies remain).
1467 			 */
1468 			if (ld_vers_find(name, hash, mv->mv_vdp->vd_deps) ==
1469 			    NULL)
1470 				if (aplist_append(&mv->mv_vdp->vd_deps, vdp,
1471 				    AL_CNT_VERDESCS) == NULL)
1472 					return (FALSE);
1473 
1474 			if (vdp->vd_ref == NULL)
1475 				vdp->vd_ref = mv->mv_vdp;
1476 			break;
1477 
1478 		case TK_SEMICOLON:
1479 			done = TRUE;
1480 			break;
1481 
1482 		default:
1483 			mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMEND),
1484 			    ld_map_tokenstr(tok, &tkv, &inv_buf));
1485 			return (FALSE);
1486 		}
1487 	}
1488 
1489 	return (TRUE);
1490 }
1491