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